| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/threading/worker_pool.h" |
| |
| #include "base/bind.h" |
| #include "base/compiler_specific.h" |
| #include "base/lazy_instance.h" |
| #include "base/task_runner.h" |
| #include "base/threading/post_task_and_reply_impl.h" |
| #include "base/tracked_objects.h" |
| |
| namespace base { |
| |
| namespace { |
| |
| class PostTaskAndReplyWorkerPool : public internal::PostTaskAndReplyImpl { |
| public: |
| PostTaskAndReplyWorkerPool(bool task_is_slow) : task_is_slow_(task_is_slow) { |
| } |
| |
| private: |
| virtual bool PostTask(const tracked_objects::Location& from_here, |
| const Closure& task) override { |
| return WorkerPool::PostTask(from_here, task, task_is_slow_); |
| } |
| |
| bool task_is_slow_; |
| }; |
| |
| // WorkerPoolTaskRunner --------------------------------------------- |
| // A TaskRunner which posts tasks to a WorkerPool with a |
| // fixed ShutdownBehavior. |
| // |
| // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). |
| class WorkerPoolTaskRunner : public TaskRunner { |
| public: |
| WorkerPoolTaskRunner(bool tasks_are_slow); |
| |
| // TaskRunner implementation |
| virtual bool PostDelayedTask(const tracked_objects::Location& from_here, |
| const Closure& task, |
| TimeDelta delay) override; |
| #if defined(COBALT) |
| virtual bool PostBlockingTask(const tracked_objects::Location& from_here, |
| const Closure& task) override; |
| #endif |
| virtual bool RunsTasksOnCurrentThread() const override; |
| |
| private: |
| virtual ~WorkerPoolTaskRunner(); |
| |
| // Helper function for posting a delayed task. Asserts that the delay is |
| // zero because non-zero delays are not supported. |
| bool PostDelayedTaskAssertZeroDelay( |
| const tracked_objects::Location& from_here, |
| const Closure& task, |
| base::TimeDelta delay); |
| |
| const bool tasks_are_slow_; |
| |
| DISALLOW_COPY_AND_ASSIGN(WorkerPoolTaskRunner); |
| }; |
| |
| WorkerPoolTaskRunner::WorkerPoolTaskRunner(bool tasks_are_slow) |
| : tasks_are_slow_(tasks_are_slow) { |
| } |
| |
| WorkerPoolTaskRunner::~WorkerPoolTaskRunner() { |
| } |
| |
| bool WorkerPoolTaskRunner::PostDelayedTask( |
| const tracked_objects::Location& from_here, |
| const Closure& task, |
| TimeDelta delay) { |
| return PostDelayedTaskAssertZeroDelay(from_here, task, delay); |
| } |
| |
| #if defined(COBALT) |
| bool WorkerPoolTaskRunner::PostBlockingTask( |
| const tracked_objects::Location& from_here, |
| const Closure& task) { |
| return WorkerPool::PostBlockingTask(from_here, task, tasks_are_slow_); |
| } |
| #endif |
| |
| bool WorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { |
| return WorkerPool::RunsTasksOnCurrentThread(); |
| } |
| |
| bool WorkerPoolTaskRunner::PostDelayedTaskAssertZeroDelay( |
| const tracked_objects::Location& from_here, |
| const Closure& task, |
| base::TimeDelta delay) { |
| DCHECK_EQ(delay.InMillisecondsRoundedUp(), 0) |
| << "WorkerPoolTaskRunner does not support non-zero delays"; |
| return WorkerPool::PostTask(from_here, task, tasks_are_slow_); |
| } |
| |
| struct TaskRunnerHolder { |
| TaskRunnerHolder() { |
| taskrunners_[0] = new WorkerPoolTaskRunner(false); |
| taskrunners_[1] = new WorkerPoolTaskRunner(true); |
| } |
| scoped_refptr<TaskRunner> taskrunners_[2]; |
| }; |
| |
| base::LazyInstance<TaskRunnerHolder>::Leaky |
| g_taskrunners = LAZY_INSTANCE_INITIALIZER; |
| |
| } // namespace |
| |
| bool WorkerPool::PostTaskAndReply(const tracked_objects::Location& from_here, |
| const Closure& task, |
| const Closure& reply, |
| bool task_is_slow) { |
| return PostTaskAndReplyWorkerPool(task_is_slow).PostTaskAndReply( |
| from_here, task, reply); |
| } |
| |
| // static |
| const scoped_refptr<TaskRunner>& |
| WorkerPool::GetTaskRunner(bool tasks_are_slow) { |
| return g_taskrunners.Get().taskrunners_[tasks_are_slow]; |
| } |
| |
| } // namespace base |