Home | History | Annotate | Download | only in threading
      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