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 14 namespace base { 15 16 namespace { 17 18 class 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). 38 class 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 63 WorkerPoolTaskRunner::WorkerPoolTaskRunner(bool tasks_are_slow) 64 : tasks_are_slow_(tasks_are_slow) { 65 } 66 67 WorkerPoolTaskRunner::~WorkerPoolTaskRunner() { 68 } 69 70 bool 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 77 bool WorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { 78 return WorkerPool::RunsTasksOnCurrentThread(); 79 } 80 81 bool 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 90 struct TaskRunnerHolder { 91 TaskRunnerHolder() { 92 taskrunners_[0] = new WorkerPoolTaskRunner(false); 93 taskrunners_[1] = new WorkerPoolTaskRunner(true); 94 } 95 scoped_refptr<TaskRunner> taskrunners_[2]; 96 }; 97 98 base::LazyInstance<TaskRunnerHolder>::Leaky 99 g_taskrunners = LAZY_INSTANCE_INITIALIZER; 100 101 } // namespace 102 103 bool 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 112 const scoped_refptr<TaskRunner>& 113 WorkerPool::GetTaskRunner(bool tasks_are_slow) { 114 return g_taskrunners.Get().taskrunners_[tasks_are_slow]; 115 } 116 117 } // namespace base 118