Home | History | Annotate | Download | only in resources
      1 // Copyright 2013 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 #ifndef CC_RESOURCES_WORKER_POOL_H_
      6 #define CC_RESOURCES_WORKER_POOL_H_
      7 
      8 #include <deque>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/cancelable_callback.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "base/message_loop/message_loop.h"
     17 #include "cc/base/cc_export.h"
     18 #include "cc/base/scoped_ptr_hash_map.h"
     19 
     20 namespace cc {
     21 namespace internal {
     22 
     23 class CC_EXPORT WorkerPoolTask
     24     : public base::RefCountedThreadSafe<WorkerPoolTask> {
     25  public:
     26   virtual void RunOnWorkerThread(unsigned thread_index) = 0;
     27   virtual void CompleteOnOriginThread() = 0;
     28 
     29   void DidSchedule();
     30   void WillRun();
     31   void DidRun();
     32   void WillComplete();
     33   void DidComplete();
     34 
     35   bool HasFinishedRunning() const;
     36   bool HasCompleted() const;
     37 
     38  protected:
     39   friend class base::RefCountedThreadSafe<WorkerPoolTask>;
     40 
     41   WorkerPoolTask();
     42   virtual ~WorkerPoolTask();
     43 
     44  private:
     45   bool did_schedule_;
     46   bool did_run_;
     47   bool did_complete_;
     48 };
     49 
     50 class CC_EXPORT GraphNode {
     51  public:
     52   typedef std::vector<GraphNode*> Vector;
     53 
     54   GraphNode(internal::WorkerPoolTask* task, unsigned priority);
     55   ~GraphNode();
     56 
     57   WorkerPoolTask* task() { return task_; }
     58 
     59   void add_dependent(GraphNode* dependent) {
     60     DCHECK(dependent);
     61     dependents_.push_back(dependent);
     62   }
     63   const Vector& dependents() const { return dependents_; }
     64 
     65   unsigned priority() const { return priority_; }
     66 
     67   unsigned num_dependencies() const { return num_dependencies_; }
     68   void add_dependency() { ++num_dependencies_; }
     69   void remove_dependency() {
     70     DCHECK(num_dependencies_);
     71     --num_dependencies_;
     72   }
     73 
     74  private:
     75   WorkerPoolTask* task_;
     76   Vector dependents_;
     77   unsigned priority_;
     78   unsigned num_dependencies_;
     79 
     80   DISALLOW_COPY_AND_ASSIGN(GraphNode);
     81 };
     82 
     83 }  // namespace internal
     84 }  // namespace cc
     85 
     86 #if defined(COMPILER_GCC)
     87 namespace BASE_HASH_NAMESPACE {
     88 template <> struct hash<cc::internal::WorkerPoolTask*> {
     89   size_t operator()(cc::internal::WorkerPoolTask* ptr) const {
     90     return hash<size_t>()(reinterpret_cast<size_t>(ptr));
     91   }
     92 };
     93 }  // namespace BASE_HASH_NAMESPACE
     94 #endif  // COMPILER
     95 
     96 namespace cc {
     97 
     98 // A worker thread pool that runs tasks provided by task graph and
     99 // guarantees completion of all pending tasks at shutdown.
    100 class CC_EXPORT WorkerPool {
    101  public:
    102   virtual ~WorkerPool();
    103 
    104   // Tells the worker pool to shutdown and returns once all pending tasks have
    105   // completed.
    106   virtual void Shutdown();
    107 
    108   // Force a check for completed tasks.
    109   virtual void CheckForCompletedTasks();
    110 
    111  protected:
    112   // A task graph contains a unique set of tasks with edges between
    113   // dependencies pointing in the direction of the dependents. Each task
    114   // need to be assigned a unique priority and a run count that matches
    115   // the number of dependencies.
    116   typedef ScopedPtrHashMap<internal::WorkerPoolTask*, internal::GraphNode>
    117       GraphNodeMap;
    118   typedef GraphNodeMap TaskGraph;
    119 
    120   WorkerPool(size_t num_threads, const std::string& thread_name_prefix);
    121 
    122   // Schedule running of tasks in |graph|. Any previously scheduled tasks
    123   // that are not already running will be canceled. Canceled tasks don't run
    124   // but completion of them is still processed.
    125   void SetTaskGraph(TaskGraph* graph);
    126 
    127  private:
    128   class Inner;
    129   friend class Inner;
    130 
    131   typedef std::vector<scoped_refptr<internal::WorkerPoolTask> > TaskVector;
    132 
    133   void ProcessCompletedTasks(const TaskVector& completed_tasks);
    134 
    135   bool in_dispatch_completion_callbacks_;
    136 
    137   // Hide the gory details of the worker pool in |inner_|.
    138   const scoped_ptr<Inner> inner_;
    139 };
    140 
    141 }  // namespace cc
    142 
    143 #endif  // CC_RESOURCES_WORKER_POOL_H_
    144