15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/worker_pool.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/post_task_and_reply_impl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PostTaskAndReplyWorkerPool : public internal::PostTaskAndReplyImpl {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit PostTaskAndReplyWorkerPool(bool task_is_slow)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : task_is_slow_(task_is_slow) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool PostTask(const tracked_objects::Location& from_here,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const Closure& task) OVERRIDE {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WorkerPool::PostTask(from_here, task, task_is_slow_);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool task_is_slow_;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WorkerPoolTaskRunner ---------------------------------------------
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A TaskRunner which posts tasks to a WorkerPool with a
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fixed ShutdownBehavior.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that this class is RefCountedThreadSafe (inherited from TaskRunner).
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WorkerPoolTaskRunner : public TaskRunner {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit WorkerPoolTaskRunner(bool tasks_are_slow);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TaskRunner implementation
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const Closure& task,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               TimeDelta delay) OVERRIDE;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RunsTasksOnCurrentThread() const OVERRIDE;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WorkerPoolTaskRunner();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper function for posting a delayed task. Asserts that the delay is
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // zero because non-zero delays are not supported.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool PostDelayedTaskAssertZeroDelay(
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const tracked_objects::Location& from_here,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const Closure& task,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta delay);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool tasks_are_slow_;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WorkerPoolTaskRunner);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WorkerPoolTaskRunner::WorkerPoolTaskRunner(bool tasks_are_slow)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : tasks_are_slow_(tasks_are_slow) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WorkerPoolTaskRunner::~WorkerPoolTaskRunner() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerPoolTaskRunner::PostDelayedTask(
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const tracked_objects::Location& from_here,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Closure& task,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TimeDelta delay) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PostDelayedTaskAssertZeroDelay(from_here, task, delay);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerPoolTaskRunner::RunsTasksOnCurrentThread() const {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WorkerPool::RunsTasksOnCurrentThread();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerPoolTaskRunner::PostDelayedTaskAssertZeroDelay(
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const tracked_objects::Location& from_here,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Closure& task,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta delay) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(delay.InMillisecondsRoundedUp(), 0)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "WorkerPoolTaskRunner does not support non-zero delays";
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WorkerPool::PostTask(from_here, task, tasks_are_slow_);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TaskRunnerHolder {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TaskRunnerHolder() {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    taskrunners_[0] = new WorkerPoolTaskRunner(false);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    taskrunners_[1] = new WorkerPoolTaskRunner(true);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TaskRunner> taskrunners_[2];
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<TaskRunnerHolder>::Leaky
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_taskrunners = LAZY_INSTANCE_INITIALIZER;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerPool::PostTaskAndReply(const tracked_objects::Location& from_here,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const Closure& task,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const Closure& reply,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  bool task_is_slow) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PostTaskAndReplyWorkerPool(task_is_slow).PostTaskAndReply(
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      from_here, task, reply);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const scoped_refptr<TaskRunner>&
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WorkerPool::GetTaskRunner(bool tasks_are_slow) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_taskrunners.Get().taskrunners_[tasks_are_slow];
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
118