worker_pool.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/worker_pool.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/post_task_and_reply_impl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PostTaskAndReplyWorkerPool : public internal::PostTaskAndReplyImpl {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostTaskAndReplyWorkerPool(bool task_is_slow) : task_is_slow_(task_is_slow) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool PostTask(const tracked_objects::Location& from_here,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const Closure& task) OVERRIDE {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WorkerPool::PostTask(from_here, task, task_is_slow_);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool task_is_slow_;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WorkerPoolTaskRunner ---------------------------------------------
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A TaskRunner which posts tasks to a WorkerPool with a
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fixed ShutdownBehavior.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that this class is RefCountedThreadSafe (inherited from TaskRunner).
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WorkerPoolTaskRunner : public TaskRunner {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WorkerPoolTaskRunner(bool tasks_are_slow);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TaskRunner implementation
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const Closure& task,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               TimeDelta delay) OVERRIDE;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RunsTasksOnCurrentThread() const OVERRIDE;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WorkerPoolTaskRunner();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper function for posting a delayed task. Asserts that the delay is
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // zero because non-zero delays are not supported.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool PostDelayedTaskAssertZeroDelay(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const tracked_objects::Location& from_here,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const Closure& task,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta delay);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool tasks_are_slow_;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WorkerPoolTaskRunner);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WorkerPoolTaskRunner::WorkerPoolTaskRunner(bool tasks_are_slow)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : tasks_are_slow_(tasks_are_slow) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WorkerPoolTaskRunner::~WorkerPoolTaskRunner() {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerPoolTaskRunner::PostDelayedTask(
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const tracked_objects::Location& from_here,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Closure& task,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TimeDelta delay) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PostDelayedTaskAssertZeroDelay(from_here, task, delay);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerPoolTaskRunner::RunsTasksOnCurrentThread() const {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WorkerPool::RunsTasksOnCurrentThread();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerPoolTaskRunner::PostDelayedTaskAssertZeroDelay(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const tracked_objects::Location& from_here,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Closure& task,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta delay) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(delay.InMillisecondsRoundedUp(), 0)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "WorkerPoolTaskRunner does not support non-zero delays";
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WorkerPool::PostTask(from_here, task, tasks_are_slow_);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TaskRunnerHolder {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TaskRunnerHolder() {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    taskrunners_[0] = new WorkerPoolTaskRunner(false);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    taskrunners_[1] = new WorkerPoolTaskRunner(true);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TaskRunner> taskrunners_[2];
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<TaskRunnerHolder>::Leaky
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_taskrunners = LAZY_INSTANCE_INITIALIZER;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerPool::PostTaskAndReply(const tracked_objects::Location& from_here,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const Closure& task,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const Closure& reply,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  bool task_is_slow) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PostTaskAndReplyWorkerPool(task_is_slow).PostTaskAndReply(
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      from_here, task, reply);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const scoped_refptr<TaskRunner>&
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WorkerPool::GetTaskRunner(bool tasks_are_slow) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_taskrunners.Get().taskrunners_[tasks_are_slow];
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
117