Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_TASK_SCHEDULER_SCHEDULER_WORKER_H_ | 5 #ifndef BASE_TASK_SCHEDULER_SCHEDULER_WORKER_H_ |
| 6 #define BASE_TASK_SCHEDULER_SCHEDULER_WORKER_H_ | 6 #define BASE_TASK_SCHEDULER_SCHEDULER_WORKER_H_ |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "base/base_export.h" | 10 #include "base/base_export.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 // A SchedulerWorker starts out sleeping. It is woken up by a call to WakeUp(). | 30 // A SchedulerWorker starts out sleeping. It is woken up by a call to WakeUp(). |
| 31 // After a wake-up, a SchedulerWorker runs Tasks from Sequences returned by the | 31 // After a wake-up, a SchedulerWorker runs Tasks from Sequences returned by the |
| 32 // GetWork() method of its delegate as long as it doesn't return nullptr. It | 32 // GetWork() method of its delegate as long as it doesn't return nullptr. It |
| 33 // also periodically checks with its TaskTracker whether shutdown has completed | 33 // also periodically checks with its TaskTracker whether shutdown has completed |
| 34 // and exits when it has. | 34 // and exits when it has. |
| 35 // | 35 // |
| 36 // The worker is free to release and reallocate the platform thread with | 36 // The worker is free to release and reallocate the platform thread with |
| 37 // guidance from the delegate. | 37 // guidance from the delegate. |
| 38 // | 38 // |
| 39 // This class is thread-safe. | 39 // This class is thread-safe. |
| 40 class BASE_EXPORT SchedulerWorker { | 40 class BASE_EXPORT SchedulerWorker |
| 41 : public RefCountedThreadSafe<SchedulerWorker> { | |
| 41 public: | 42 public: |
| 42 // Delegate interface for SchedulerWorker. The methods are always called from | 43 // Delegate interface for SchedulerWorker. The methods are always called from |
| 43 // the thread managed by the SchedulerWorker instance. | 44 // the thread managed by the SchedulerWorker instance. |
| 44 class Delegate { | 45 class Delegate { |
| 45 public: | 46 public: |
| 46 virtual ~Delegate() = default; | 47 virtual ~Delegate() = default; |
| 47 | 48 |
| 48 // Called by a thread managed by |worker| when it enters its main function. | 49 // Called by a thread managed by |worker| when it enters its main function. |
| 49 // If a thread is recreated after detachment, |detach_duration| is the time | 50 // If a thread is recreated after detachment, |detach_duration| is the time |
| 50 // elapsed since detachment. Otherwise, if this is the first thread created | 51 // elapsed since detachment. Otherwise, if this is the first thread created |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 88 | 89 |
| 89 enum class InitialState { ALIVE, DETACHED }; | 90 enum class InitialState { ALIVE, DETACHED }; |
| 90 | 91 |
| 91 // Creates a SchedulerWorker that runs Tasks from Sequences returned by | 92 // Creates a SchedulerWorker that runs Tasks from Sequences returned by |
| 92 // |delegate|. |priority_hint| is the preferred thread priority; the actual | 93 // |delegate|. |priority_hint| is the preferred thread priority; the actual |
| 93 // thread priority depends on shutdown state and platform capabilities. | 94 // thread priority depends on shutdown state and platform capabilities. |
| 94 // |task_tracker| is used to handle shutdown behavior of Tasks. If | 95 // |task_tracker| is used to handle shutdown behavior of Tasks. If |
| 95 // |worker_state| is DETACHED, the thread will be created upon a WakeUp(). | 96 // |worker_state| is DETACHED, the thread will be created upon a WakeUp(). |
| 96 // Returns nullptr if creating the underlying platform thread fails during | 97 // Returns nullptr if creating the underlying platform thread fails during |
| 97 // Create(). |backward_compatibility| indicates whether backward compatibility | 98 // Create(). |backward_compatibility| indicates whether backward compatibility |
| 98 // is enabled. | 99 // is enabled. |
|
gab
2017/02/21 19:01:04
Mention that Cleanup() must be called before relea
robliao
2017/02/21 22:26:57
Done.
| |
| 99 static std::unique_ptr<SchedulerWorker> Create( | 100 static scoped_refptr<SchedulerWorker> Create( |
| 100 ThreadPriority priority_hint, | 101 ThreadPriority priority_hint, |
| 101 std::unique_ptr<Delegate> delegate, | 102 std::unique_ptr<Delegate> delegate, |
| 102 TaskTracker* task_tracker, | 103 TaskTracker* task_tracker, |
| 103 InitialState initial_state, | 104 InitialState initial_state, |
| 104 SchedulerBackwardCompatibility backward_compatibility = | 105 SchedulerBackwardCompatibility backward_compatibility = |
| 105 SchedulerBackwardCompatibility::DISABLED); | 106 SchedulerBackwardCompatibility::DISABLED); |
| 106 | 107 |
| 107 // Destroying a SchedulerWorker in production is not allowed; it is always | |
| 108 // leaked. In tests, it can only be destroyed after JoinForTesting() has | |
| 109 // returned. | |
| 110 ~SchedulerWorker(); | |
| 111 | |
| 112 // Wakes up this SchedulerWorker if it wasn't already awake. After this | 108 // Wakes up this SchedulerWorker if it wasn't already awake. After this |
| 113 // is called, this SchedulerWorker will run Tasks from Sequences | 109 // is called, this SchedulerWorker will run Tasks from Sequences |
| 114 // returned by the GetWork() method of its delegate until it returns nullptr. | 110 // returned by the GetWork() method of its delegate until it returns nullptr. |
| 115 // WakeUp() may fail if the worker is detached and it fails to allocate a new | 111 // WakeUp() may fail if the worker is detached and it fails to allocate a new |
| 116 // worker. If this happens, there will be no call to GetWork(). | 112 // worker. If this happens, there will be no call to GetWork(). |
| 117 void WakeUp(); | 113 void WakeUp(); |
| 118 | 114 |
| 119 SchedulerWorker::Delegate* delegate() { return delegate_.get(); } | 115 SchedulerWorker::Delegate* delegate() { return delegate_.get(); } |
| 120 | 116 |
| 121 // Joins this SchedulerWorker. If a Task is already running, it will be | 117 // Joins this SchedulerWorker. If a Task is already running, it will be |
| 122 // allowed to complete its execution. This can only be called once. | 118 // allowed to complete its execution. This can only be called once. |
| 123 // | 119 // |
| 124 // Note: A thread that detaches before JoinForTesting() is called may still be | 120 // Note: A thread that detaches before JoinForTesting() is called may still be |
| 125 // running after JoinForTesting() returns. However, it can't run tasks after | 121 // running after JoinForTesting() returns. However, it can't run tasks after |
| 126 // JoinForTesting() returns. | 122 // JoinForTesting() returns. |
| 127 void JoinForTesting(); | 123 void JoinForTesting(); |
| 128 | 124 |
| 129 // Returns true if the worker is alive. | 125 // Returns true if the worker is alive. |
| 130 bool ThreadAliveForTesting() const; | 126 bool ThreadAliveForTesting() const; |
| 131 | 127 |
| 128 // Makes a request to cleanup the worker. This may be called from any thread. | |
| 129 // The caller is expected to release its reference to this object after | |
| 130 // calling Cleanup(). Further method calls after Cleanup() returns are | |
| 131 // undefined. | |
| 132 // | |
| 133 // Expected Usage: | |
| 134 // scoped_refptr<SchedulerWorker> worker_ = /* Existing Worker */ | |
| 135 // worker_->Cleanup(); | |
| 136 // worker_ = nullptr; | |
| 137 void Cleanup(); | |
| 138 | |
| 132 private: | 139 private: |
| 140 friend class RefCountedThreadSafe<SchedulerWorker>; | |
| 133 class Thread; | 141 class Thread; |
| 142 enum class DetachNotify { | |
| 143 // Do not notify any component. | |
| 144 SILENT, | |
| 145 // Notify the delegate. | |
| 146 DELEGATE, | |
| 147 }; | |
| 134 | 148 |
| 135 SchedulerWorker(ThreadPriority thread_priority, | 149 SchedulerWorker(ThreadPriority thread_priority, |
| 136 std::unique_ptr<Delegate> delegate, | 150 std::unique_ptr<Delegate> delegate, |
| 137 TaskTracker* task_tracker, | 151 TaskTracker* task_tracker, |
| 138 SchedulerBackwardCompatibility backward_compatibility); | 152 SchedulerBackwardCompatibility backward_compatibility); |
| 153 ~SchedulerWorker(); | |
| 139 | 154 |
| 140 // Returns the thread instance if the detach was successful so that it can be | 155 // Returns ownership of the thread instance when appropriate so that it can be |
| 141 // freed upon termination of the thread. | 156 // freed upon termination of the thread. If ownership transfer is not |
| 142 // If the detach is not possible, returns nullptr. | 157 // possible, returns nullptr. |
| 143 std::unique_ptr<SchedulerWorker::Thread> Detach(); | 158 std::unique_ptr<SchedulerWorker::Thread> DetachThreadObject( |
| 159 DetachNotify detach_notify); | |
| 144 | 160 |
| 145 void CreateThread(); | 161 void CreateThread(); |
| 146 | 162 |
| 147 void CreateThreadAssertSynchronized(); | 163 void CreateThreadAssertSynchronized(); |
| 148 | 164 |
| 149 // Synchronizes access to |thread_|. | 165 bool ShouldExit(); |
| 166 | |
| 167 // Synchronizes access to |thread_| (read+write) as well as |should_exit_| | |
| 168 // (write-only). See Cleanup() for details. | |
| 150 mutable SchedulerLock thread_lock_; | 169 mutable SchedulerLock thread_lock_; |
| 151 | 170 |
| 171 AtomicFlag should_exit_; | |
| 172 | |
| 152 // The underlying thread for this SchedulerWorker. | 173 // The underlying thread for this SchedulerWorker. |
| 174 // The thread object will be cleaned up by the running thread unless we join | |
| 175 // against the thread. Joining requires the thread object to remain alive for | |
| 176 // the Thread::Join() call. | |
| 153 std::unique_ptr<Thread> thread_; | 177 std::unique_ptr<Thread> thread_; |
| 154 | 178 |
| 155 const ThreadPriority priority_hint_; | 179 const ThreadPriority priority_hint_; |
| 156 | 180 |
| 157 const std::unique_ptr<Delegate> delegate_; | 181 const std::unique_ptr<Delegate> delegate_; |
| 158 TaskTracker* const task_tracker_; | 182 TaskTracker* const task_tracker_; |
| 159 | 183 |
| 160 #if defined(OS_WIN) | 184 #if defined(OS_WIN) |
| 161 const SchedulerBackwardCompatibility backward_compatibility_; | 185 const SchedulerBackwardCompatibility backward_compatibility_; |
| 162 #endif | 186 #endif |
| 163 | 187 |
| 164 // Set once JoinForTesting() has been called. | 188 // Set once JoinForTesting() has been called. |
| 165 AtomicFlag should_exit_for_testing_; | 189 AtomicFlag join_called_for_testing_; |
| 166 | 190 |
| 167 DISALLOW_COPY_AND_ASSIGN(SchedulerWorker); | 191 DISALLOW_COPY_AND_ASSIGN(SchedulerWorker); |
| 168 }; | 192 }; |
| 169 | 193 |
| 170 } // namespace internal | 194 } // namespace internal |
| 171 } // namespace base | 195 } // namespace base |
| 172 | 196 |
| 173 #endif // BASE_TASK_SCHEDULER_SCHEDULER_WORKER_H_ | 197 #endif // BASE_TASK_SCHEDULER_SCHEDULER_WORKER_H_ |
| OLD | NEW |