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/macros.h" 11 #include "base/task_runner.h" 12 #include "base/threading/post_task_and_reply_impl.h" 13 #include "base/tracked_objects.h" 14 15 namespace base { 16 17 namespace { 18 19 class PostTaskAndReplyWorkerPool : public internal::PostTaskAndReplyImpl { 20 public: 21 explicit PostTaskAndReplyWorkerPool(bool task_is_slow) 22 : task_is_slow_(task_is_slow) { 23 } 24 ~PostTaskAndReplyWorkerPool() override = default; 25 26 private: 27 bool PostTask(const tracked_objects::Location& from_here, 28 const Closure& task) override { 29 return WorkerPool::PostTask(from_here, task, task_is_slow_); 30 } 31 32 bool task_is_slow_; 33 }; 34 35 // WorkerPoolTaskRunner --------------------------------------------- 36 // A TaskRunner which posts tasks to a WorkerPool with a 37 // fixed ShutdownBehavior. 38 // 39 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). 40 class WorkerPoolTaskRunner : public TaskRunner { 41 public: 42 explicit WorkerPoolTaskRunner(bool tasks_are_slow); 43 44 // TaskRunner implementation 45 bool PostDelayedTask(const tracked_objects::Location& from_here, 46 const Closure& task, 47 TimeDelta delay) override; 48 bool RunsTasksOnCurrentThread() const override; 49 50 private: 51 ~WorkerPoolTaskRunner() override; 52 53 // Helper function for posting a delayed task. Asserts that the delay is 54 // zero because non-zero delays are not supported. 55 bool PostDelayedTaskAssertZeroDelay( 56 const tracked_objects::Location& from_here, 57 const Closure& task, 58 base::TimeDelta delay); 59 60 const bool tasks_are_slow_; 61 62 DISALLOW_COPY_AND_ASSIGN(WorkerPoolTaskRunner); 63 }; 64 65 WorkerPoolTaskRunner::WorkerPoolTaskRunner(bool tasks_are_slow) 66 : tasks_are_slow_(tasks_are_slow) { 67 } 68 69 WorkerPoolTaskRunner::~WorkerPoolTaskRunner() { 70 } 71 72 bool WorkerPoolTaskRunner::PostDelayedTask( 73 const tracked_objects::Location& from_here, 74 const Closure& task, 75 TimeDelta delay) { 76 return PostDelayedTaskAssertZeroDelay(from_here, task, delay); 77 } 78 79 bool WorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { 80 return WorkerPool::RunsTasksOnCurrentThread(); 81 } 82 83 bool WorkerPoolTaskRunner::PostDelayedTaskAssertZeroDelay( 84 const tracked_objects::Location& from_here, 85 const Closure& task, 86 base::TimeDelta delay) { 87 DCHECK_EQ(delay.InMillisecondsRoundedUp(), 0) 88 << "WorkerPoolTaskRunner does not support non-zero delays"; 89 return WorkerPool::PostTask(from_here, task, tasks_are_slow_); 90 } 91 92 struct TaskRunnerHolder { 93 TaskRunnerHolder() { 94 taskrunners_[0] = new WorkerPoolTaskRunner(false); 95 taskrunners_[1] = new WorkerPoolTaskRunner(true); 96 } 97 scoped_refptr<TaskRunner> taskrunners_[2]; 98 }; 99 100 base::LazyInstance<TaskRunnerHolder>::Leaky 101 g_taskrunners = LAZY_INSTANCE_INITIALIZER; 102 103 } // namespace 104 105 bool WorkerPool::PostTaskAndReply(const tracked_objects::Location& from_here, 106 const Closure& task, 107 const Closure& reply, 108 bool task_is_slow) { 109 // Do not report PostTaskAndReplyRelay leaks in tests. There's nothing we can 110 // do about them because WorkerPool doesn't have a flushing API. 111 // http://crbug.com/248513 112 // http://crbug.com/290897 113 return PostTaskAndReplyWorkerPool(task_is_slow).PostTaskAndReply( 114 from_here, task, reply); 115 } 116 117 // static 118 const scoped_refptr<TaskRunner>& 119 WorkerPool::GetTaskRunner(bool tasks_are_slow) { 120 return g_taskrunners.Get().taskrunners_[tasks_are_slow]; 121 } 122 123 } // namespace base 124