// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CC_RESOURCES_WORKER_POOL_H_ #define CC_RESOURCES_WORKER_POOL_H_ #include #include #include #include "base/cancelable_callback.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "cc/base/cc_export.h" #include "cc/base/scoped_ptr_hash_map.h" namespace cc { namespace internal { class CC_EXPORT WorkerPoolTask : public base::RefCountedThreadSafe { public: virtual void RunOnWorkerThread(unsigned thread_index) = 0; virtual void CompleteOnOriginThread() = 0; void DidSchedule(); void WillRun(); void DidRun(); void WillComplete(); void DidComplete(); bool HasFinishedRunning() const; bool HasCompleted() const; protected: friend class base::RefCountedThreadSafe; WorkerPoolTask(); virtual ~WorkerPoolTask(); private: bool did_schedule_; bool did_run_; bool did_complete_; }; class CC_EXPORT GraphNode { public: typedef std::vector Vector; GraphNode(internal::WorkerPoolTask* task, unsigned priority); ~GraphNode(); WorkerPoolTask* task() { return task_; } void add_dependent(GraphNode* dependent) { DCHECK(dependent); dependents_.push_back(dependent); } const Vector& dependents() const { return dependents_; } unsigned priority() const { return priority_; } unsigned num_dependencies() const { return num_dependencies_; } void add_dependency() { ++num_dependencies_; } void remove_dependency() { DCHECK(num_dependencies_); --num_dependencies_; } private: WorkerPoolTask* task_; Vector dependents_; unsigned priority_; unsigned num_dependencies_; DISALLOW_COPY_AND_ASSIGN(GraphNode); }; } // namespace internal } // namespace cc #if defined(COMPILER_GCC) namespace BASE_HASH_NAMESPACE { template <> struct hash { size_t operator()(cc::internal::WorkerPoolTask* ptr) const { return hash()(reinterpret_cast(ptr)); } }; } // namespace BASE_HASH_NAMESPACE #endif // COMPILER namespace cc { // A worker thread pool that runs tasks provided by task graph and // guarantees completion of all pending tasks at shutdown. class CC_EXPORT WorkerPool { public: virtual ~WorkerPool(); // Tells the worker pool to shutdown and returns once all pending tasks have // completed. virtual void Shutdown(); // Force a check for completed tasks. virtual void CheckForCompletedTasks(); protected: // A task graph contains a unique set of tasks with edges between // dependencies pointing in the direction of the dependents. Each task // need to be assigned a unique priority and a run count that matches // the number of dependencies. typedef ScopedPtrHashMap GraphNodeMap; typedef GraphNodeMap TaskGraph; WorkerPool(size_t num_threads, const std::string& thread_name_prefix); // Schedule running of tasks in |graph|. Any previously scheduled tasks // that are not already running will be canceled. Canceled tasks don't run // but completion of them is still processed. void SetTaskGraph(TaskGraph* graph); private: class Inner; friend class Inner; typedef std::vector > TaskVector; void ProcessCompletedTasks(const TaskVector& completed_tasks); bool in_dispatch_completion_callbacks_; // Hide the gory details of the worker pool in |inner_|. const scoped_ptr inner_; }; } // namespace cc #endif // CC_RESOURCES_WORKER_POOL_H_