1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/threading/worker_pool.h" 6 7#include "base/bind.h" 8#include "base/compiler_specific.h" 9#include "base/lazy_instance.h" 10#include "base/task_runner.h" 11#include "base/threading/post_task_and_reply_impl.h" 12#include "base/tracked_objects.h" 13 14namespace base { 15 16namespace { 17 18class PostTaskAndReplyWorkerPool : public internal::PostTaskAndReplyImpl { 19 public: 20 explicit PostTaskAndReplyWorkerPool(bool task_is_slow) 21 : task_is_slow_(task_is_slow) { 22 } 23 24 private: 25 virtual bool PostTask(const tracked_objects::Location& from_here, 26 const Closure& task) OVERRIDE { 27 return WorkerPool::PostTask(from_here, task, task_is_slow_); 28 } 29 30 bool task_is_slow_; 31}; 32 33// WorkerPoolTaskRunner --------------------------------------------- 34// A TaskRunner which posts tasks to a WorkerPool with a 35// fixed ShutdownBehavior. 36// 37// Note that this class is RefCountedThreadSafe (inherited from TaskRunner). 38class WorkerPoolTaskRunner : public TaskRunner { 39 public: 40 explicit WorkerPoolTaskRunner(bool tasks_are_slow); 41 42 // TaskRunner implementation 43 virtual bool PostDelayedTask(const tracked_objects::Location& from_here, 44 const Closure& task, 45 TimeDelta delay) OVERRIDE; 46 virtual bool RunsTasksOnCurrentThread() const OVERRIDE; 47 48 private: 49 virtual ~WorkerPoolTaskRunner(); 50 51 // Helper function for posting a delayed task. Asserts that the delay is 52 // zero because non-zero delays are not supported. 53 bool PostDelayedTaskAssertZeroDelay( 54 const tracked_objects::Location& from_here, 55 const Closure& task, 56 base::TimeDelta delay); 57 58 const bool tasks_are_slow_; 59 60 DISALLOW_COPY_AND_ASSIGN(WorkerPoolTaskRunner); 61}; 62 63WorkerPoolTaskRunner::WorkerPoolTaskRunner(bool tasks_are_slow) 64 : tasks_are_slow_(tasks_are_slow) { 65} 66 67WorkerPoolTaskRunner::~WorkerPoolTaskRunner() { 68} 69 70bool WorkerPoolTaskRunner::PostDelayedTask( 71 const tracked_objects::Location& from_here, 72 const Closure& task, 73 TimeDelta delay) { 74 return PostDelayedTaskAssertZeroDelay(from_here, task, delay); 75} 76 77bool WorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { 78 return WorkerPool::RunsTasksOnCurrentThread(); 79} 80 81bool WorkerPoolTaskRunner::PostDelayedTaskAssertZeroDelay( 82 const tracked_objects::Location& from_here, 83 const Closure& task, 84 base::TimeDelta delay) { 85 DCHECK_EQ(delay.InMillisecondsRoundedUp(), 0) 86 << "WorkerPoolTaskRunner does not support non-zero delays"; 87 return WorkerPool::PostTask(from_here, task, tasks_are_slow_); 88} 89 90struct TaskRunnerHolder { 91 TaskRunnerHolder() { 92 taskrunners_[0] = new WorkerPoolTaskRunner(false); 93 taskrunners_[1] = new WorkerPoolTaskRunner(true); 94 } 95 scoped_refptr<TaskRunner> taskrunners_[2]; 96}; 97 98base::LazyInstance<TaskRunnerHolder>::Leaky 99 g_taskrunners = LAZY_INSTANCE_INITIALIZER; 100 101} // namespace 102 103bool WorkerPool::PostTaskAndReply(const tracked_objects::Location& from_here, 104 const Closure& task, 105 const Closure& reply, 106 bool task_is_slow) { 107 return PostTaskAndReplyWorkerPool(task_is_slow).PostTaskAndReply( 108 from_here, task, reply); 109} 110 111// static 112const scoped_refptr<TaskRunner>& 113WorkerPool::GetTaskRunner(bool tasks_are_slow) { 114 return g_taskrunners.Get().taskrunners_[tasks_are_slow]; 115} 116 117} // namespace base 118