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 |