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