worker_thread.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Copyright 2016 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. #ifndef BASE_TASK_THREAD_POOL_WORKER_THREAD_H_
  5. #define BASE_TASK_THREAD_POOL_WORKER_THREAD_H_
  6. #include <memory>
  7. #include "base/base_export.h"
  8. #include "base/macros.h"
  9. #include "base/memory/ref_counted.h"
  10. #include "base/synchronization/atomic_flag.h"
  11. #include "base/synchronization/waitable_event.h"
  12. #include "base/task/common/checked_lock.h"
  13. #include "base/task/thread_pool/task_source.h"
  14. #include "base/task/thread_pool/tracked_ref.h"
  15. #include "base/thread_annotations.h"
  16. #include "base/threading/platform_thread.h"
  17. #include "base/time/time.h"
  18. #include "build/build_config.h"
  19. namespace base {
  20. class WorkerThreadObserver;
  21. namespace internal {
  22. class TaskTracker;
  23. // A worker that manages a single thread to run Tasks from TaskSources returned
  24. // by a delegate.
  25. //
  26. // A WorkerThread starts out sleeping. It is woken up by a call to WakeUp().
  27. // After a wake-up, a WorkerThread runs Tasks from TaskSources returned by
  28. // the GetWork() method of its delegate as long as it doesn't return nullptr. It
  29. // also periodically checks with its TaskTracker whether shutdown has completed
  30. // and exits when it has.
  31. //
  32. // This class is thread-safe.
  33. class BASE_EXPORT WorkerThread : public RefCountedThreadSafe<WorkerThread>,
  34. public PlatformThread::Delegate {
  35. public:
  36. // Labels this WorkerThread's association. This doesn't affect any logic
  37. // but will add a stack frame labeling this thread for ease of stack trace
  38. // identification.
  39. enum class ThreadLabel {
  40. POOLED,
  41. SHARED,
  42. DEDICATED,
  43. #if defined(OS_WIN)
  44. SHARED_COM,
  45. DEDICATED_COM,
  46. #endif // defined(OS_WIN)
  47. };
  48. // Delegate interface for WorkerThread. All methods are called from the
  49. // thread managed by the WorkerThread instance.
  50. class BASE_EXPORT Delegate {
  51. public:
  52. virtual ~Delegate() = default;
  53. // Returns the ThreadLabel the Delegate wants its WorkerThreads' stacks
  54. // to be labeled with.
  55. virtual ThreadLabel GetThreadLabel() const = 0;
  56. // Called by |worker|'s thread when it enters its main function.
  57. virtual void OnMainEntry(const WorkerThread* worker) = 0;
  58. // Called by |worker|'s thread to get a TaskSource from which to run a Task.
  59. virtual RegisteredTaskSource GetWork(WorkerThread* worker) = 0;
  60. // Called by the WorkerThread after it ran a Task. If the Task's
  61. // TaskSource should be reenqueued, it is passed to |task_source|.
  62. // Otherwise, |task_source| is nullptr.
  63. virtual void DidProcessTask(RegisteredTaskSource task_source) = 0;
  64. // Called to determine how long to sleep before the next call to GetWork().
  65. // GetWork() may be called before this timeout expires if the worker's
  66. // WakeUp() method is called.
  67. virtual TimeDelta GetSleepTimeout() = 0;
  68. // Called by the WorkerThread's thread to wait for work. Override this
  69. // method if the thread in question needs special handling to go to sleep.
  70. // |wake_up_event| is a manually resettable event and is signaled on
  71. // WorkerThread::WakeUp()
  72. virtual void WaitForWork(WaitableEvent* wake_up_event);
  73. // Called by |worker|'s thread right before the main function exits. The
  74. // Delegate is free to release any associated resources in this call. It is
  75. // guaranteed that WorkerThread won't access the Delegate or the
  76. // TaskTracker after calling OnMainExit() on the Delegate.
  77. virtual void OnMainExit(WorkerThread* worker) {}
  78. };
  79. // Creates a WorkerThread that runs Tasks from TaskSources returned by
  80. // |delegate|. No actual thread will be created for this WorkerThread
  81. // before Start() is called. |priority_hint| is the preferred thread priority;
  82. // the actual thread priority depends on shutdown state and platform
  83. // capabilities. |task_tracker| is used to handle shutdown behavior of Tasks.
  84. // |predecessor_lock| is a lock that is allowed to be held when calling
  85. // methods on this WorkerThread. |backward_compatibility| indicates
  86. // whether backward compatibility is enabled. Either JoinForTesting() or
  87. // Cleanup() must be called before releasing the last external reference.
  88. WorkerThread(ThreadPriority priority_hint,
  89. std::unique_ptr<Delegate> delegate,
  90. TrackedRef<TaskTracker> task_tracker,
  91. const CheckedLock* predecessor_lock = nullptr);
  92. // Creates a thread to back the WorkerThread. The thread will be in a wait
  93. // state pending a WakeUp() call. No thread will be created if Cleanup() was
  94. // called. If specified, |worker_thread_observer| will be notified when the
  95. // worker enters and exits its main function. It must not be destroyed before
  96. // JoinForTesting() has returned (must never be destroyed in production).
  97. // Returns true on success.
  98. bool Start(WorkerThreadObserver* worker_thread_observer = nullptr);
  99. // Wakes up this WorkerThread if it wasn't already awake. After this is
  100. // called, this WorkerThread will run Tasks from TaskSources returned by
  101. // the GetWork() method of its delegate until it returns nullptr. No-op if
  102. // Start() wasn't called. DCHECKs if called after Start() has failed or after
  103. // Cleanup() has been called.
  104. void WakeUp();
  105. WorkerThread::Delegate* delegate() { return delegate_.get(); }
  106. // Joins this WorkerThread. If a Task is already running, it will be
  107. // allowed to complete its execution. This can only be called once.
  108. //
  109. // Note: A thread that detaches before JoinForTesting() is called may still be
  110. // running after JoinForTesting() returns. However, it can't run tasks after
  111. // JoinForTesting() returns.
  112. void JoinForTesting();
  113. // Returns true if the worker is alive.
  114. bool ThreadAliveForTesting() const;
  115. // Makes a request to cleanup the worker. This may be called from any thread.
  116. // The caller is expected to release its reference to this object after
  117. // calling Cleanup(). Further method calls after Cleanup() returns are
  118. // undefined.
  119. //
  120. // Expected Usage:
  121. // scoped_refptr<WorkerThread> worker_ = /* Existing Worker */
  122. // worker_->Cleanup();
  123. // worker_ = nullptr;
  124. void Cleanup();
  125. // Informs this WorkerThread about periods during which it is not being
  126. // used. Thread-safe.
  127. void BeginUnusedPeriod();
  128. void EndUnusedPeriod();
  129. // Returns the last time this WorkerThread was used. Returns a null time if
  130. // this WorkerThread is currently in-use. Thread-safe.
  131. TimeTicks GetLastUsedTime() const;
  132. private:
  133. friend class RefCountedThreadSafe<WorkerThread>;
  134. class Thread;
  135. ~WorkerThread() override;
  136. bool ShouldExit() const;
  137. // Returns the thread priority to use based on the priority hint, current
  138. // shutdown state, and platform capabilities.
  139. ThreadPriority GetDesiredThreadPriority() const;
  140. // Changes the thread priority to |desired_thread_priority|. Must be called on
  141. // the thread managed by |this|.
  142. void UpdateThreadPriority(ThreadPriority desired_thread_priority);
  143. // PlatformThread::Delegate:
  144. void ThreadMain() override;
  145. // Dummy frames to act as "RunLabeledWorker()" (see RunMain() below). Their
  146. // impl is aliased to prevent compiler/linker from optimizing them out.
  147. void RunPooledWorker();
  148. void RunBackgroundPooledWorker();
  149. void RunSharedWorker();
  150. void RunBackgroundSharedWorker();
  151. void RunDedicatedWorker();
  152. void RunBackgroundDedicatedWorker();
  153. #if defined(OS_WIN)
  154. void RunSharedCOMWorker();
  155. void RunBackgroundSharedCOMWorker();
  156. void RunDedicatedCOMWorker();
  157. void RunBackgroundDedicatedCOMWorker();
  158. #endif // defined(OS_WIN)
  159. // The real main, invoked through :
  160. // ThreadMain() -> RunLabeledWorker() -> RunWorker().
  161. // "RunLabeledWorker()" is a dummy frame based on ThreadLabel+ThreadPriority
  162. // and used to easily identify threads in stack traces.
  163. void RunWorker();
  164. // Self-reference to prevent destruction of |this| while the thread is alive.
  165. // Set in Start() before creating the thread. Reset in ThreadMain() before the
  166. // thread exits. No lock required because the first access occurs before the
  167. // thread is created and the second access occurs on the thread.
  168. scoped_refptr<WorkerThread> self_;
  169. mutable CheckedLock thread_lock_;
  170. // Handle for the thread managed by |this|.
  171. PlatformThreadHandle thread_handle_ GUARDED_BY(thread_lock_);
  172. // The last time this worker was used by its owner (e.g. to process work or
  173. // stand as a required idle thread).
  174. TimeTicks last_used_time_ GUARDED_BY(thread_lock_);
  175. // Event to wake up the thread managed by |this|.
  176. WaitableEvent wake_up_event_{WaitableEvent::ResetPolicy::AUTOMATIC,
  177. WaitableEvent::InitialState::NOT_SIGNALED};
  178. // Whether the thread should exit. Set by Cleanup().
  179. AtomicFlag should_exit_;
  180. const std::unique_ptr<Delegate> delegate_;
  181. const TrackedRef<TaskTracker> task_tracker_;
  182. // Optional observer notified when a worker enters and exits its main
  183. // function. Set in Start() and never modified afterwards.
  184. WorkerThreadObserver* worker_thread_observer_ = nullptr;
  185. // Desired thread priority.
  186. const ThreadPriority priority_hint_;
  187. // Actual thread priority. Can be different than |priority_hint_| depending on
  188. // system capabilities and shutdown state. No lock required because all post-
  189. // construction accesses occur on the thread.
  190. ThreadPriority current_thread_priority_;
  191. // Set once JoinForTesting() has been called.
  192. AtomicFlag join_called_for_testing_;
  193. DISALLOW_COPY_AND_ASSIGN(WorkerThread);
  194. };
  195. } // namespace internal
  196. } // namespace base
  197. #endif // BASE_TASK_THREAD_POOL_WORKER_THREAD_H_