summaryrefslogtreecommitdiff
path: root/base/threading
diff options
context:
space:
mode:
Diffstat (limited to 'base/threading')
-rw-r--r--base/threading/post_task_and_reply_impl.cc26
-rw-r--r--base/threading/post_task_and_reply_impl.h6
-rw-r--r--base/threading/sequenced_worker_pool.cc75
-rw-r--r--base/threading/sequenced_worker_pool.h17
-rw-r--r--base/threading/thread.cc2
-rw-r--r--base/threading/thread_unittest.cc4
-rw-r--r--base/threading/worker_pool.cc14
-rw-r--r--base/threading/worker_pool.h6
-rw-r--r--base/threading/worker_pool_posix.cc10
-rw-r--r--base/threading/worker_pool_posix.h2
10 files changed, 92 insertions, 70 deletions
diff --git a/base/threading/post_task_and_reply_impl.cc b/base/threading/post_task_and_reply_impl.cc
index d16f8bd225..cddb8981ad 100644
--- a/base/threading/post_task_and_reply_impl.cc
+++ b/base/threading/post_task_and_reply_impl.cc
@@ -29,8 +29,8 @@ namespace {
class PostTaskAndReplyRelay {
public:
PostTaskAndReplyRelay(const tracked_objects::Location& from_here,
- Closure task,
- Closure reply)
+ OnceClosure task,
+ OnceClosure reply)
: sequence_checker_(),
from_here_(from_here),
origin_task_runner_(SequencedTaskRunnerHandle::Get()),
@@ -39,12 +39,10 @@ class PostTaskAndReplyRelay {
~PostTaskAndReplyRelay() {
DCHECK(sequence_checker_.CalledOnValidSequence());
- task_.Reset();
- reply_.Reset();
}
void RunTaskAndPostReply() {
- task_.Run();
+ std::move(task_).Run();
origin_task_runner_->PostTask(
from_here_, Bind(&PostTaskAndReplyRelay::RunReplyAndSelfDestruct,
base::Unretained(this)));
@@ -54,12 +52,12 @@ class PostTaskAndReplyRelay {
void RunReplyAndSelfDestruct() {
DCHECK(sequence_checker_.CalledOnValidSequence());
- // Force |task_| to be released before |reply_| is to ensure that no one
- // accidentally depends on |task_| keeping one of its arguments alive while
- // |reply_| is executing.
- task_.Reset();
+ // Ensure |task_| has already been released before |reply_| to ensure that
+ // no one accidentally depends on |task_| keeping one of its arguments alive
+ // while |reply_| is executing.
+ DCHECK(!task_);
- reply_.Run();
+ std::move(reply_).Run();
// Cue mission impossible theme.
delete this;
@@ -68,8 +66,8 @@ class PostTaskAndReplyRelay {
const SequenceChecker sequence_checker_;
const tracked_objects::Location from_here_;
const scoped_refptr<SequencedTaskRunner> origin_task_runner_;
- Closure reply_;
- Closure task_;
+ OnceClosure reply_;
+ OnceClosure task_;
};
} // namespace
@@ -78,8 +76,8 @@ namespace internal {
bool PostTaskAndReplyImpl::PostTaskAndReply(
const tracked_objects::Location& from_here,
- Closure task,
- Closure reply) {
+ OnceClosure task,
+ OnceClosure reply) {
DCHECK(!task.is_null()) << from_here.ToString();
DCHECK(!reply.is_null()) << from_here.ToString();
PostTaskAndReplyRelay* relay =
diff --git a/base/threading/post_task_and_reply_impl.h b/base/threading/post_task_and_reply_impl.h
index a02c32ec8c..00aee6d0ed 100644
--- a/base/threading/post_task_and_reply_impl.h
+++ b/base/threading/post_task_and_reply_impl.h
@@ -29,12 +29,12 @@ class BASE_EXPORT PostTaskAndReplyImpl {
// SequencedTaskRunnerHandle::IsSet(). Both |task| and |reply| are guaranteed
// to be deleted on the sequence or thread that called this.
bool PostTaskAndReply(const tracked_objects::Location& from_here,
- Closure task,
- Closure reply);
+ OnceClosure task,
+ OnceClosure reply);
private:
virtual bool PostTask(const tracked_objects::Location& from_here,
- Closure task) = 0;
+ OnceClosure task) = 0;
};
} // namespace internal
diff --git a/base/threading/sequenced_worker_pool.cc b/base/threading/sequenced_worker_pool.cc
index ecf6e2c8e0..1d8a67c2e0 100644
--- a/base/threading/sequenced_worker_pool.cc
+++ b/base/threading/sequenced_worker_pool.cc
@@ -97,12 +97,15 @@ struct SequencedTask : public TrackingInfo {
~SequencedTask() {}
+ SequencedTask(SequencedTask&&) = default;
+ SequencedTask& operator=(SequencedTask&&) = default;
+
int sequence_token_id;
int trace_id;
int64_t sequence_task_number;
SequencedWorkerPool::WorkerShutdown shutdown_behavior;
tracked_objects::Location posted_from;
- Closure task;
+ OnceClosure task;
// Non-delayed tasks and delayed tasks are managed together by time-to-run
// order. We calculate the time by adding the posted time and the given delay.
@@ -144,7 +147,7 @@ class SequencedWorkerPoolTaskRunner : public TaskRunner {
// TaskRunner implementation
bool PostDelayedTask(const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) override;
bool RunsTasksOnCurrentThread() const override;
@@ -168,7 +171,7 @@ SequencedWorkerPoolTaskRunner::~SequencedWorkerPoolTaskRunner() {
bool SequencedWorkerPoolTaskRunner::PostDelayedTask(
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) {
if (delay.is_zero()) {
return pool_->PostWorkerTaskWithShutdownBehavior(from_here, std::move(task),
@@ -198,13 +201,13 @@ class SequencedWorkerPool::PoolSequencedTaskRunner
// TaskRunner implementation
bool PostDelayedTask(const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) override;
bool RunsTasksOnCurrentThread() const override;
// SequencedTaskRunner implementation
bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) override;
private:
@@ -233,7 +236,7 @@ SequencedWorkerPool::PoolSequencedTaskRunner::
bool SequencedWorkerPool::PoolSequencedTaskRunner::PostDelayedTask(
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) {
if (delay.is_zero()) {
return pool_->PostSequencedWorkerTaskWithShutdownBehavior(
@@ -250,7 +253,7 @@ bool SequencedWorkerPool::PoolSequencedTaskRunner::
bool SequencedWorkerPool::PoolSequencedTaskRunner::PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) {
// There's no way to run nested tasks, so simply forward to
// PostDelayedTask.
@@ -353,7 +356,7 @@ class SequencedWorkerPool::Inner {
SequenceToken sequence_token,
WorkerShutdown shutdown_behavior,
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay);
bool RunsTasksOnCurrentThread() const;
@@ -398,8 +401,7 @@ class SequencedWorkerPool::Inner {
// Returns true if the task may run at some point in the future and false if
// it will definitely not run.
// Coalesce upon resolution of http://crbug.com/622400.
- bool PostTaskToTaskScheduler(const SequencedTask& sequenced,
- const TimeDelta& delay);
+ bool PostTaskToTaskScheduler(SequencedTask sequenced, const TimeDelta& delay);
// Returns the TaskScheduler TaskRunner for the specified |sequence_token_id|
// and |traits|.
@@ -697,8 +699,10 @@ bool SequencedWorkerPool::Inner::PostTask(
SequenceToken sequence_token,
WorkerShutdown shutdown_behavior,
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) {
+ DCHECK(task);
+
// TODO(fdoray): Uncomment this DCHECK. It is initially commented to avoid a
// revert of the CL that adds debug::DumpWithoutCrashing() if it fails on the
// waterfall. https://crbug.com/622400
@@ -758,20 +762,22 @@ bool SequencedWorkerPool::Inner::PostTask(
// See on top of the file why we don't compile this on Arc++.
#if 0
if (g_all_pools_state == AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) {
- if (!PostTaskToTaskScheduler(sequenced, delay))
+ if (!PostTaskToTaskScheduler(std::move(sequenced), delay))
return false;
} else {
#endif
- pending_tasks_.insert(sequenced);
+ SequencedWorkerPool::WorkerShutdown shutdown_behavior =
+ sequenced.shutdown_behavior;
+ pending_tasks_.insert(std::move(sequenced));
- if (sequenced.shutdown_behavior == BLOCK_SHUTDOWN)
+ if (shutdown_behavior == BLOCK_SHUTDOWN)
blocking_shutdown_pending_task_count_++;
create_thread_id = PrepareToStartAdditionalThreadIfHelpful();
- }
#if 0
- }
+ }
#endif
+ }
// Use != REDIRECTED_TO_TASK_SCHEDULER instead of == USE_WORKER_POOL to ensure
// correct behavior if a task is posted to a SequencedWorkerPool before
@@ -803,7 +809,7 @@ bool SequencedWorkerPool::Inner::PostTask(
}
bool SequencedWorkerPool::Inner::PostTaskToTaskScheduler(
- const SequencedTask& sequenced,
+ SequencedTask sequenced,
const TimeDelta& delay) {
#if 1
NOTREACHED();
@@ -837,7 +843,8 @@ bool SequencedWorkerPool::Inner::PostTaskToTaskScheduler(
.WithPriority(task_priority_)
.WithShutdownBehavior(task_shutdown_behavior);
return GetTaskSchedulerTaskRunner(sequenced.sequence_token_id, traits)
- ->PostDelayedTask(sequenced.posted_from, sequenced.task, delay);
+ ->PostDelayedTask(sequenced.posted_from, std::move(sequenced.task),
+ delay);
#endif
}
@@ -1263,7 +1270,11 @@ SequencedWorkerPool::Inner::GetWorkStatus SequencedWorkerPool::Inner::GetWork(
// refcounted, so we just need to keep a copy of them alive until the lock
// is exited. The calling code can just clear() the vector they passed to
// us once the lock is exited to make this happen.
- delete_these_outside_lock->push_back(*i);
+ //
+ // The const_cast here is safe since the object is erased from
+ // |pending_tasks_| soon after the move.
+ delete_these_outside_lock->push_back(
+ std::move(const_cast<SequencedTask&>(*i)));
pending_tasks_.erase(i++);
continue;
}
@@ -1274,14 +1285,18 @@ SequencedWorkerPool::Inner::GetWorkStatus SequencedWorkerPool::Inner::GetWork(
status = GET_WORK_WAIT;
if (cleanup_state_ == CLEANUP_RUNNING) {
// Deferred tasks are deleted when cleaning up, see Inner::ThreadLoop.
- delete_these_outside_lock->push_back(*i);
+ // The const_cast here is safe since the object is erased from
+ // |pending_tasks_| soon after the move.
+ delete_these_outside_lock->push_back(
+ std::move(const_cast<SequencedTask&>(*i)));
pending_tasks_.erase(i);
}
break;
}
- // Found a runnable task.
- *task = *i;
+ // Found a runnable task. The const_cast is safe here since the object is
+ // erased from |pending_tasks_| soon after the move.
+ *task = std::move(const_cast<SequencedTask&>(*i));
pending_tasks_.erase(i);
if (task->shutdown_behavior == BLOCK_SHUTDOWN) {
blocking_shutdown_pending_task_count_--;
@@ -1558,14 +1573,14 @@ SequencedWorkerPool::GetTaskRunnerWithShutdownBehavior(
bool SequencedWorkerPool::PostWorkerTask(
const tracked_objects::Location& from_here,
- Closure task) {
+ OnceClosure task) {
return inner_->PostTask(NULL, SequenceToken(), BLOCK_SHUTDOWN, from_here,
std::move(task), TimeDelta());
}
bool SequencedWorkerPool::PostDelayedWorkerTask(
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) {
WorkerShutdown shutdown_behavior =
delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN;
@@ -1575,7 +1590,7 @@ bool SequencedWorkerPool::PostDelayedWorkerTask(
bool SequencedWorkerPool::PostWorkerTaskWithShutdownBehavior(
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
WorkerShutdown shutdown_behavior) {
return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here,
std::move(task), TimeDelta());
@@ -1584,7 +1599,7 @@ bool SequencedWorkerPool::PostWorkerTaskWithShutdownBehavior(
bool SequencedWorkerPool::PostSequencedWorkerTask(
SequenceToken sequence_token,
const tracked_objects::Location& from_here,
- Closure task) {
+ OnceClosure task) {
return inner_->PostTask(NULL, sequence_token, BLOCK_SHUTDOWN, from_here,
std::move(task), TimeDelta());
}
@@ -1592,7 +1607,7 @@ bool SequencedWorkerPool::PostSequencedWorkerTask(
bool SequencedWorkerPool::PostDelayedSequencedWorkerTask(
SequenceToken sequence_token,
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) {
WorkerShutdown shutdown_behavior =
delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN;
@@ -1603,7 +1618,7 @@ bool SequencedWorkerPool::PostDelayedSequencedWorkerTask(
bool SequencedWorkerPool::PostNamedSequencedWorkerTask(
const std::string& token_name,
const tracked_objects::Location& from_here,
- Closure task) {
+ OnceClosure task) {
DCHECK(!token_name.empty());
return inner_->PostTask(&token_name, SequenceToken(), BLOCK_SHUTDOWN,
from_here, std::move(task), TimeDelta());
@@ -1612,7 +1627,7 @@ bool SequencedWorkerPool::PostNamedSequencedWorkerTask(
bool SequencedWorkerPool::PostSequencedWorkerTaskWithShutdownBehavior(
SequenceToken sequence_token,
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
WorkerShutdown shutdown_behavior) {
return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here,
std::move(task), TimeDelta());
@@ -1620,7 +1635,7 @@ bool SequencedWorkerPool::PostSequencedWorkerTaskWithShutdownBehavior(
bool SequencedWorkerPool::PostDelayedTask(
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) {
return PostDelayedWorkerTask(from_here, std::move(task), delay);
}
diff --git a/base/threading/sequenced_worker_pool.h b/base/threading/sequenced_worker_pool.h
index 8cdeb0b5db..e577e1be11 100644
--- a/base/threading/sequenced_worker_pool.h
+++ b/base/threading/sequenced_worker_pool.h
@@ -275,7 +275,8 @@ class BASE_EXPORT SequencedWorkerPool : public TaskRunner {
//
// Returns true if the task was posted successfully. This may fail during
// shutdown regardless of the specified ShutdownBehavior.
- bool PostWorkerTask(const tracked_objects::Location& from_here, Closure task);
+ bool PostWorkerTask(const tracked_objects::Location& from_here,
+ OnceClosure task);
// Same as PostWorkerTask but allows a delay to be specified (although doing
// so changes the shutdown behavior). The task will be run after the given
@@ -287,13 +288,13 @@ class BASE_EXPORT SequencedWorkerPool : public TaskRunner {
// task will be guaranteed to run to completion before shutdown
// (BLOCK_SHUTDOWN semantics).
bool PostDelayedWorkerTask(const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay);
// Same as PostWorkerTask but allows specification of the shutdown behavior.
bool PostWorkerTaskWithShutdownBehavior(
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
WorkerShutdown shutdown_behavior);
// Like PostWorkerTask above, but provides sequencing semantics. This means
@@ -309,13 +310,13 @@ class BASE_EXPORT SequencedWorkerPool : public TaskRunner {
// shutdown regardless of the specified ShutdownBehavior.
bool PostSequencedWorkerTask(SequenceToken sequence_token,
const tracked_objects::Location& from_here,
- Closure task);
+ OnceClosure task);
// Like PostSequencedWorkerTask above, but allows you to specify a named
// token, which saves an extra call to GetNamedSequenceToken.
bool PostNamedSequencedWorkerTask(const std::string& token_name,
const tracked_objects::Location& from_here,
- Closure task);
+ OnceClosure task);
// Same as PostSequencedWorkerTask but allows a delay to be specified
// (although doing so changes the shutdown behavior). The task will be run
@@ -329,7 +330,7 @@ class BASE_EXPORT SequencedWorkerPool : public TaskRunner {
bool PostDelayedSequencedWorkerTask(
SequenceToken sequence_token,
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay);
// Same as PostSequencedWorkerTask but allows specification of the shutdown
@@ -337,12 +338,12 @@ class BASE_EXPORT SequencedWorkerPool : public TaskRunner {
bool PostSequencedWorkerTaskWithShutdownBehavior(
SequenceToken sequence_token,
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
WorkerShutdown shutdown_behavior);
// TaskRunner implementation. Forwards to PostDelayedWorkerTask().
bool PostDelayedTask(const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) override;
bool RunsTasksOnCurrentThread() const override;
diff --git a/base/threading/thread.cc b/base/threading/thread.cc
index c30320f0dc..0aeed2a9e4 100644
--- a/base/threading/thread.cc
+++ b/base/threading/thread.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
+#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/thread_id_name_manager.h"
#include "base/threading/thread_local.h"
#include "base/threading/thread_restrictions.h"
@@ -290,6 +291,7 @@ void Thread::ThreadMain() {
// Complete the initialization of our Thread object.
PlatformThread::SetName(name_.c_str());
+ ANNOTATE_THREAD_NAME(name_.c_str()); // Tell the name to race detector.
// Lazily initialize the |message_loop| so that it can run on this thread.
DCHECK(message_loop_);
diff --git a/base/threading/thread_unittest.cc b/base/threading/thread_unittest.cc
index af8347432b..0cb964e8f7 100644
--- a/base/threading/thread_unittest.cc
+++ b/base/threading/thread_unittest.cc
@@ -32,6 +32,8 @@ typedef PlatformTest ThreadTest;
namespace {
void ToggleValue(bool* value) {
+ ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean "
+ "in base/thread_unittest");
*value = !*value;
}
@@ -39,6 +41,8 @@ class SleepInsideInitThread : public Thread {
public:
SleepInsideInitThread() : Thread("none") {
init_called_ = false;
+ ANNOTATE_BENIGN_RACE(
+ this, "Benign test-only data race on vptr - http://crbug.com/98219");
}
~SleepInsideInitThread() override { Stop(); }
diff --git a/base/threading/worker_pool.cc b/base/threading/worker_pool.cc
index bc313ce25b..26ff10f1f5 100644
--- a/base/threading/worker_pool.cc
+++ b/base/threading/worker_pool.cc
@@ -27,7 +27,7 @@ class PostTaskAndReplyWorkerPool : public internal::PostTaskAndReplyImpl {
private:
bool PostTask(const tracked_objects::Location& from_here,
- Closure task) override {
+ OnceClosure task) override {
return WorkerPool::PostTask(from_here, std::move(task), task_is_slow_);
}
@@ -45,7 +45,7 @@ class WorkerPoolTaskRunner : public TaskRunner {
// TaskRunner implementation
bool PostDelayedTask(const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) override;
bool RunsTasksOnCurrentThread() const override;
@@ -56,7 +56,7 @@ class WorkerPoolTaskRunner : public TaskRunner {
// zero because non-zero delays are not supported.
bool PostDelayedTaskAssertZeroDelay(
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
base::TimeDelta delay);
const bool tasks_are_slow_;
@@ -73,7 +73,7 @@ WorkerPoolTaskRunner::~WorkerPoolTaskRunner() {
bool WorkerPoolTaskRunner::PostDelayedTask(
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
TimeDelta delay) {
return PostDelayedTaskAssertZeroDelay(from_here, std::move(task), delay);
}
@@ -84,7 +84,7 @@ bool WorkerPoolTaskRunner::RunsTasksOnCurrentThread() const {
bool WorkerPoolTaskRunner::PostDelayedTaskAssertZeroDelay(
const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
base::TimeDelta delay) {
DCHECK_EQ(delay.InMillisecondsRoundedUp(), 0)
<< "WorkerPoolTaskRunner does not support non-zero delays";
@@ -102,8 +102,8 @@ struct TaskRunnerHolder {
} // namespace
bool WorkerPool::PostTaskAndReply(const tracked_objects::Location& from_here,
- Closure task,
- Closure reply,
+ OnceClosure task,
+ OnceClosure reply,
bool task_is_slow) {
// Do not report PostTaskAndReplyRelay leaks in tests. There's nothing we can
// do about them because WorkerPool doesn't have a flushing API.
diff --git a/base/threading/worker_pool.h b/base/threading/worker_pool.h
index d97dbd6a69..d1c666d2f9 100644
--- a/base/threading/worker_pool.h
+++ b/base/threading/worker_pool.h
@@ -32,15 +32,15 @@ class BASE_EXPORT WorkerPool {
// false if |task| could not be posted to a worker thread. Regardless of
// return value, ownership of |task| is transferred to the worker pool.
static bool PostTask(const tracked_objects::Location& from_here,
- Closure task,
+ OnceClosure task,
bool task_is_slow);
// Just like TaskRunner::PostTaskAndReply, except the destination
// for |task| is a worker thread and you can specify |task_is_slow| just
// like you can for PostTask above.
static bool PostTaskAndReply(const tracked_objects::Location& from_here,
- Closure task,
- Closure reply,
+ OnceClosure task,
+ OnceClosure reply,
bool task_is_slow);
// Return true if the current thread is one that this WorkerPool runs tasks
diff --git a/base/threading/worker_pool_posix.cc b/base/threading/worker_pool_posix.cc
index e0efa463f7..851480adda 100644
--- a/base/threading/worker_pool_posix.cc
+++ b/base/threading/worker_pool_posix.cc
@@ -49,7 +49,7 @@ class WorkerPoolImpl {
~WorkerPoolImpl() = delete;
void PostTask(const tracked_objects::Location& from_here,
- base::Closure task,
+ base::OnceClosure task,
bool task_is_slow);
private:
@@ -61,7 +61,7 @@ WorkerPoolImpl::WorkerPoolImpl()
kIdleSecondsBeforeExit)) {}
void WorkerPoolImpl::PostTask(const tracked_objects::Location& from_here,
- base::Closure task,
+ base::OnceClosure task,
bool task_is_slow) {
pool_->PostTask(from_here, std::move(task));
}
@@ -114,7 +114,7 @@ void WorkerThread::ThreadMain() {
// static
bool WorkerPool::PostTask(const tracked_objects::Location& from_here,
- base::Closure task,
+ base::OnceClosure task,
bool task_is_slow) {
g_lazy_worker_pool.Pointer()->PostTask(from_here, std::move(task),
task_is_slow);
@@ -140,12 +140,14 @@ PosixDynamicThreadPool::~PosixDynamicThreadPool() {
void PosixDynamicThreadPool::PostTask(
const tracked_objects::Location& from_here,
- base::Closure task) {
+ base::OnceClosure task) {
PendingTask pending_task(from_here, std::move(task));
AddTask(&pending_task);
}
void PosixDynamicThreadPool::AddTask(PendingTask* pending_task) {
+ DCHECK(pending_task);
+ DCHECK(pending_task->task);
AutoLock locked(lock_);
pending_tasks_.push(std::move(*pending_task));
diff --git a/base/threading/worker_pool_posix.h b/base/threading/worker_pool_posix.h
index cfa50c21dd..0b10adf8f3 100644
--- a/base/threading/worker_pool_posix.h
+++ b/base/threading/worker_pool_posix.h
@@ -51,7 +51,7 @@ class BASE_EXPORT PosixDynamicThreadPool
int idle_seconds_before_exit);
// Adds |task| to the thread pool.
- void PostTask(const tracked_objects::Location& from_here, Closure task);
+ void PostTask(const tracked_objects::Location& from_here, OnceClosure task);
// Worker thread method to wait for up to |idle_seconds_before_exit| for more
// work from the thread pool. Returns NULL if no work is available.