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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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. |
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 // All further method calls are undefined after this calling this function. | |
gab
2017/02/17 21:38:35
"this calling this", but I'd just say last sentenc
robliao
2017/02/17 22:04:31
Done and done.
| |
130 void Cleanup(); | |
gab
2017/02/17 21:38:35
Need to update CL description? (i.e. not RequestTh
robliao
2017/02/17 22:04:31
Done.
| |
131 | |
132 private: | 132 private: |
133 friend class RefCountedThreadSafe<SchedulerWorker>; | |
133 class Thread; | 134 class Thread; |
135 enum class DetachNotify { | |
136 // Do not notify any component. | |
137 SILENT, | |
138 // Notify the delegate. | |
139 DELEGATE, | |
140 }; | |
134 | 141 |
135 SchedulerWorker(ThreadPriority thread_priority, | 142 SchedulerWorker(ThreadPriority thread_priority, |
136 std::unique_ptr<Delegate> delegate, | 143 std::unique_ptr<Delegate> delegate, |
137 TaskTracker* task_tracker, | 144 TaskTracker* task_tracker, |
138 SchedulerBackwardCompatibility backward_compatibility); | 145 SchedulerBackwardCompatibility backward_compatibility); |
146 ~SchedulerWorker(); | |
139 | 147 |
140 // Returns the thread instance if the detach was successful so that it can be | 148 // Returns ownership of the thread instance when appropriate so that it can be |
141 // freed upon termination of the thread. | 149 // freed upon termination of the thread. If ownership transfer is not |
142 // If the detach is not possible, returns nullptr. | 150 // possible, returns nullptr. |
143 std::unique_ptr<SchedulerWorker::Thread> Detach(); | 151 std::unique_ptr<SchedulerWorker::Thread> DetachThreadObject( |
152 DetachNotify detach_notify); | |
144 | 153 |
145 void CreateThread(); | 154 void CreateThread(); |
146 | 155 |
147 void CreateThreadAssertSynchronized(); | 156 void CreateThreadAssertSynchronized(); |
148 | 157 |
149 // Synchronizes access to |thread_|. | 158 bool ShouldExit(); |
159 | |
160 // Synchronizes access to |thread_| and |should_exit_|. | |
150 mutable SchedulerLock thread_lock_; | 161 mutable SchedulerLock thread_lock_; |
151 | 162 |
163 bool should_exit_ = false; | |
fdoray
2017/02/17 20:28:04
Ping change to AtomicFlag?
So you don't have to a
robliao
2017/02/17 20:38:58
Actually we do.
Threads A and B.
A: Cleanup(), se
| |
164 | |
152 // The underlying thread for this SchedulerWorker. | 165 // The underlying thread for this SchedulerWorker. |
166 // The thread object will be cleaned up by the running thread unless we join | |
167 // against the thread. Joining requires the thread object to remain alive for | |
168 // the Thread::Join() call. | |
153 std::unique_ptr<Thread> thread_; | 169 std::unique_ptr<Thread> thread_; |
154 | 170 |
155 const ThreadPriority priority_hint_; | 171 const ThreadPriority priority_hint_; |
156 | 172 |
157 const std::unique_ptr<Delegate> delegate_; | 173 const std::unique_ptr<Delegate> delegate_; |
158 TaskTracker* const task_tracker_; | 174 TaskTracker* const task_tracker_; |
159 | 175 |
160 #if defined(OS_WIN) | 176 #if defined(OS_WIN) |
161 const SchedulerBackwardCompatibility backward_compatibility_; | 177 const SchedulerBackwardCompatibility backward_compatibility_; |
162 #endif | 178 #endif |
163 | 179 |
164 // Set once JoinForTesting() has been called. | 180 // Set once JoinForTesting() has been called. |
165 AtomicFlag should_exit_for_testing_; | 181 AtomicFlag join_called_for_testing_; |
166 | 182 |
167 DISALLOW_COPY_AND_ASSIGN(SchedulerWorker); | 183 DISALLOW_COPY_AND_ASSIGN(SchedulerWorker); |
168 }; | 184 }; |
169 | 185 |
170 } // namespace internal | 186 } // namespace internal |
171 } // namespace base | 187 } // namespace base |
172 | 188 |
173 #endif // BASE_TASK_SCHEDULER_SCHEDULER_WORKER_H_ | 189 #endif // BASE_TASK_SCHEDULER_SCHEDULER_WORKER_H_ |
OLD | NEW |