Index: base/task_scheduler/thread_pool.h |
diff --git a/base/task_scheduler/thread_pool.h b/base/task_scheduler/thread_pool.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b4ae5b386ae323e41b79bdd889c28ea81dd24d83 |
--- /dev/null |
+++ b/base/task_scheduler/thread_pool.h |
@@ -0,0 +1,131 @@ |
+// Copyright 2016 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 BASE_TASK_SCHEDULER_THREAD_POOL_H_ |
+#define BASE_TASK_SCHEDULER_THREAD_POOL_H_ |
+ |
+#include <stddef.h> |
+ |
+#include <stack> |
+#include <vector> |
+ |
+#include "base/base_export.h" |
+#include "base/macros.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/synchronization/condition_variable.h" |
+#include "base/task_runner.h" |
+#include "base/task_scheduler/priority_queue.h" |
+#include "base/task_scheduler/scheduler_lock.h" |
+#include "base/task_scheduler/scheduler_worker_thread.h" |
+#include "base/task_scheduler/sequence.h" |
+#include "base/task_scheduler/task_traits.h" |
+#include "base/threading/platform_thread.h" |
+#include "base/threading/thread_local.h" |
+ |
+namespace base { |
+namespace internal { |
+ |
+struct SequenceSortKey; |
+class TaskTracker; |
+ |
+// A pool of threads that run Tasks. This class is thread-safe. |
+class BASE_EXPORT ThreadPool { |
+ public: |
+ // Creates a ThreadPool with |num_threads| threads of priority |
+ // |thread_priority|. |ran_task_from_sequence_callback| is invoked after a |
+ // thread of this ThreadPool tries to run a Task from a Sequence. |
+ // |task_tracker| is used to handle shutdown behavior of Tasks. Returns |
+ // nullptr if when it fails to create a ThreadPool with at least one thread. |
+ static scoped_ptr<ThreadPool> CreateThreadPool( |
+ ThreadPriority thread_priority, |
+ size_t num_threads, |
+ const SchedulerWorkerThread::RanTaskFromSequenceCallback& |
+ ran_task_from_sequence_callback, |
+ TaskTracker* task_tracker); |
+ |
+ // Destroying a ThreadPool in production is not allowed; it is always leaked. |
+ // In tests, it can only be destroyed after JoinForTesting() has returned. |
+ ~ThreadPool(); |
+ |
+ // Returns a TaskRunner whose PostTask invocations will result in scheduling |
+ // Tasks with |traits| and |execution_mode| in this ThreadPool. |
+ scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits( |
+ const TaskTraits& traits, |
+ ExecutionMode execution_mode); |
+ |
+ // Reinserts |sequence| in |shared_priority_queue_| with |sequence_sort_key| |
+ // after |worker_thread| has run a Task from it. Note that |worker_thread| |
robliao
2016/03/31 22:48:56
The second part of this is an implementation detai
fdoray
2016/04/01 16:02:52
Done.
robliao
2016/04/01 19:14:49
Looking at the code side-by-side, do we need worke
fdoray
2016/04/01 20:16:45
Removed it.
|
+ // doesn't necessarily belong to this ThreadPool. |
+ void ReinsertSequence(const SchedulerWorkerThread* worker_thread, |
+ scoped_refptr<Sequence> sequence, |
+ const SequenceSortKey& sequence_sort_key); |
+ |
+ // Waits until all threads are idle. |
+ void WaitForAllWorkerThreadsIdleForTesting(); |
+ |
+ // Joins all threads of this ThreadPool. Tasks that are already running are |
+ // allowed to complete their execution. This can only be called once. |
+ void JoinForTesting(); |
+ |
+ private: |
+ ThreadPool(ThreadPriority thread_priority, |
+ size_t num_threads, |
+ const SchedulerWorkerThread::RanTaskFromSequenceCallback& |
+ ran_task_from_sequence_callback, |
+ TaskTracker* task_tracker); |
+ |
+ // Wakes up one thread from this ThreadPool if they aren't all busy. |
+ void WakeUpOneThread(); |
+ |
+ // Adds |worker_thread| to |idle_worker_threads_stack_|. |
+ void AddToIdleSchedulerWorkerThreadsStack( |
+ SchedulerWorkerThread* worker_thread); |
+ |
+ // Invoked when a sequence is inserted in |shared_priority_queue_|. |
+ void SequenceInsertedInSharedPriorityQueueCallback(); |
+ |
+ // Invoked when the main function of a worker thread is entered. |
+ void MainEntryCallback() const; |
+ |
+ // Invoked by a worker thread to get a Sequence from which to run a Task. |
+ scoped_refptr<Sequence> GetWorkCallback(SchedulerWorkerThread* worker_thread); |
+ |
+ // PriorityQueue from which all threads of this ThreadPool get work. |
+ PriorityQueue shared_priority_queue_; |
+ |
+ // All worker threads owned by this ThreadPool. This is only modified by the |
+ // constructor. |
+ std::vector<scoped_ptr<SchedulerWorkerThread>> worker_threads_; |
+ |
+ // True if WakeUpOneThread() shouldn't be called when a Sequence is inserted |
+ // in |shared_priority_queue_| by a given thread. |
+ ThreadLocalBoolean no_wake_up_on_sequence_insertion_; |
+ |
+ // Synchronizes access to |idle_worker_threads_stack_| and |
+ // |idle_worker_threads_cv_|. |
+ SchedulerLock idle_worker_threads_stack_lock_; |
+ |
+ // Stack of idle worker threads. The last worker thread that became idle is on |
+ // top of the stack. |
+ std::stack<SchedulerWorkerThread*> idle_worker_threads_stack_; |
+ |
+ // Signaled when all worker threads become idle. |
+ scoped_ptr<ConditionVariable> idle_worker_threads_stack_cv_; |
+ |
+ // Synchronizes access to |join_for_testing_returned_|. |
+ SchedulerLock join_for_testing_returned_lock_; |
+ |
+ // True once JoinForTesting() has returned. |
+ bool join_for_testing_returned_ = false; |
+ |
+ TaskTracker* const task_tracker_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ThreadPool); |
+}; |
+ |
+} // namespace internal |
+} // namespace base |
+ |
+#endif // BASE_TASK_SCHEDULER_THREAD_POOL_H_ |