Commit df5685ce authored by Gabriel Charette's avatar Gabriel Charette Committed by Commit Bot

[base] Introduce base::Delete/ReleaseSoon

A git cl split will follow this CL to migrate
  BrowserThread::DeleteSoon(BrowserThread::ID, FROM_HERE, *);
to
  base::DeleteSoon(FROM_HERE, {BrowserThread::ID}, *);

and will ask owners to verify that this no-op change indeed matches
the code's intent.

R=fdoray@chromium.org

Bug: 1019767
Change-Id: I83111c55ea713f50c46761cf4d83ff593f7d505b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1890632Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Commit-Queue: Gabriel Charette <gab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#711362}
parent 99a7932c
......@@ -245,6 +245,37 @@ BASE_EXPORT scoped_refptr<SingleThreadTaskRunner> CreateCOMSTATaskRunner(
BASE_EXPORT const scoped_refptr<SequencedTaskRunner>&
GetContinuationTaskRunner();
// Helpers to send a Delete/ReleaseSoon to a new SequencedTaskRunner created
// from |traits|. The semantics match base::PostTask in that the deletion is
// guaranteed to be scheduled in order with other tasks using the same |traits|.
//
// Prefer using an existing SequencedTaskRunner's Delete/ReleaseSoon over this
// to encode execution order requirements when possible.
//
// Note: base::ThreadPool is not a valid destination as it'd result in a one-off
// parallel task which is generally ill-suited for deletion. Use an existing
// SequencedTaskRunner's DeleteSoon to post a safely ordered deletion.
template <class T>
bool DeleteSoon(const Location& from_here,
const TaskTraits& traits,
const T* object) {
DCHECK(!traits.use_thread_pool());
return CreateSequencedTaskRunner(traits)->DeleteSoon(from_here, object);
}
template <class T>
bool DeleteSoon(const Location& from_here,
const TaskTraits& traits,
std::unique_ptr<T> object) {
return DeleteSoon(from_here, traits, object.release());
}
template <class T>
void ReleaseSoon(const Location& from_here,
const TaskTraits& traits,
scoped_refptr<T>&& object) {
DCHECK(!traits.use_thread_pool());
CreateSequencedTaskRunner(traits)->ReleaseSoon(from_here, std::move(object));
}
} // namespace base
#endif // BASE_TASK_POST_TASK_H_
......@@ -401,4 +401,65 @@ TEST_F(PostTaskTestWithExecutor, PriorityInherited) {
executor_.runner()->ClearPendingTasks();
}
namespace {
class FlagOnDelete {
public:
FlagOnDelete(bool* deleted) : deleted_(deleted) {}
// Required for RefCountedData.
FlagOnDelete(FlagOnDelete&& other) : deleted_(other.deleted_) {
other.deleted_ = nullptr;
}
~FlagOnDelete() {
if (deleted_) {
EXPECT_FALSE(*deleted_);
*deleted_ = true;
}
}
private:
bool* deleted_;
DISALLOW_COPY_AND_ASSIGN(FlagOnDelete);
};
} // namespace
TEST_F(PostTaskTestWithExecutor, DeleteSoon) {
constexpr TaskTraits traits = {TestExtensionBoolTrait(),
TaskPriority::BEST_EFFORT};
bool deleted = false;
auto flag_on_delete = std::make_unique<FlagOnDelete>(&deleted);
EXPECT_CALL(executor_, CreateSequencedTaskRunner(traits)).Times(1);
base::DeleteSoon(FROM_HERE, traits, std::move(flag_on_delete));
EXPECT_FALSE(deleted);
EXPECT_TRUE(executor_.runner()->HasPendingTask());
executor_.runner()->RunPendingTasks();
EXPECT_TRUE(deleted);
}
TEST_F(PostTaskTestWithExecutor, ReleaseSoon) {
constexpr TaskTraits traits = {TestExtensionBoolTrait(),
TaskPriority::BEST_EFFORT};
bool deleted = false;
auto flag_on_delete = MakeRefCounted<RefCountedData<FlagOnDelete>>(&deleted);
EXPECT_CALL(executor_, CreateSequencedTaskRunner(traits)).Times(1);
base::ReleaseSoon(FROM_HERE, traits, std::move(flag_on_delete));
EXPECT_FALSE(deleted);
EXPECT_TRUE(executor_.runner()->HasPendingTask());
executor_.runner()->RunPendingTasks();
EXPECT_TRUE(deleted);
}
} // namespace base
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment