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