Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(803)

Side by Side Diff: base/task_scheduler/scheduler_worker.cc

Issue 2806413002: Separate the create and start phases in SchedulerSingleThreadTaskRunnerManager. (Closed)
Patch Set: CR-robliao-45-initial-state-comment Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include "base/task_scheduler/scheduler_worker.h" 5 #include "base/task_scheduler/scheduler_worker.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 if (sleep_time.is_max()) { 194 if (sleep_time.is_max()) {
195 // Calling TimedWait with TimeDelta::Max is not recommended per 195 // Calling TimedWait with TimeDelta::Max is not recommended per
196 // http://crbug.com/465948. 196 // http://crbug.com/465948.
197 wake_up_event->Wait(); 197 wake_up_event->Wait();
198 } else { 198 } else {
199 wake_up_event->TimedWait(sleep_time); 199 wake_up_event->TimedWait(sleep_time);
200 } 200 }
201 wake_up_event->Reset(); 201 wake_up_event->Reset();
202 } 202 }
203 203
204 scoped_refptr<SchedulerWorker> SchedulerWorker::Create( 204 SchedulerWorker::SchedulerWorker(
205 ThreadPriority priority_hint, 205 ThreadPriority priority_hint,
206 std::unique_ptr<Delegate> delegate, 206 std::unique_ptr<Delegate> delegate,
207 TaskTracker* task_tracker, 207 TaskTracker* task_tracker,
208 InitialState initial_state, 208 SchedulerBackwardCompatibility backward_compatibility,
209 SchedulerBackwardCompatibility backward_compatibility) { 209 InitialState initial_state)
210 scoped_refptr<SchedulerWorker> worker( 210 : priority_hint_(priority_hint),
211 new SchedulerWorker(priority_hint, std::move(delegate), task_tracker, 211 delegate_(std::move(delegate)),
212 backward_compatibility)); 212 task_tracker_(task_tracker),
213 // Creation happens before any other thread can reference this one, so no 213 #if defined(OS_WIN)
214 // synchronization is necessary. 214 backward_compatibility_(backward_compatibility),
215 if (initial_state == SchedulerWorker::InitialState::ALIVE) { 215 #endif
216 worker->CreateThread(); 216 initial_state_(initial_state) {
217 if (!worker->thread_) { 217 DCHECK(delegate_);
218 return nullptr; 218 DCHECK(task_tracker_);
219 } 219 }
220
221 bool SchedulerWorker::Start() {
222 AutoSchedulerLock auto_lock(thread_lock_);
223 DCHECK(!started_);
224 DCHECK(!thread_);
225
226 if (should_exit_.IsSet())
227 return true;
228
229 started_ = true;
230
231 if (initial_state_ == InitialState::ALIVE) {
232 CreateThread();
233 return !!thread_;
220 } 234 }
221 235
222 return worker; 236 return true;
223 } 237 }
224 238
225 void SchedulerWorker::WakeUp() { 239 void SchedulerWorker::WakeUp() {
226 AutoSchedulerLock auto_lock(thread_lock_); 240 AutoSchedulerLock auto_lock(thread_lock_);
227 241
228 DCHECK(!join_called_for_testing_.IsSet()); 242 DCHECK(!join_called_for_testing_.IsSet());
229 243
230 if (!thread_) 244 if (!thread_)
231 CreateThreadAssertSynchronized(); 245 CreateThread();
232 246
233 if (thread_) 247 if (thread_)
234 thread_->WakeUp(); 248 thread_->WakeUp();
235 } 249 }
236 250
237 void SchedulerWorker::JoinForTesting() { 251 void SchedulerWorker::JoinForTesting() {
252 DCHECK(started_);
238 DCHECK(!join_called_for_testing_.IsSet()); 253 DCHECK(!join_called_for_testing_.IsSet());
239 join_called_for_testing_.Set(); 254 join_called_for_testing_.Set();
240 255
241 std::unique_ptr<Thread> thread; 256 std::unique_ptr<Thread> thread;
242 257
243 { 258 {
244 AutoSchedulerLock auto_lock(thread_lock_); 259 AutoSchedulerLock auto_lock(thread_lock_);
245 260
246 if (thread_) { 261 if (thread_) {
247 // Make sure the thread is awake. It will see that 262 // Make sure the thread is awake. It will see that
(...skipping 11 matching lines...) Expand all
259 AutoSchedulerLock auto_lock(thread_lock_); 274 AutoSchedulerLock auto_lock(thread_lock_);
260 return !!thread_; 275 return !!thread_;
261 } 276 }
262 277
263 void SchedulerWorker::Cleanup() { 278 void SchedulerWorker::Cleanup() {
264 // |should_exit_| is synchronized with |thread_| for writes here so that we 279 // |should_exit_| is synchronized with |thread_| for writes here so that we
265 // can maintain access to |thread_| for wakeup. Otherwise, the thread may take 280 // can maintain access to |thread_| for wakeup. Otherwise, the thread may take
266 // away |thread_| for destruction. 281 // away |thread_| for destruction.
267 AutoSchedulerLock auto_lock(thread_lock_); 282 AutoSchedulerLock auto_lock(thread_lock_);
268 DCHECK(!should_exit_.IsSet()); 283 DCHECK(!should_exit_.IsSet());
269 if (thread_) { 284 should_exit_.Set();
270 should_exit_.Set(); 285 if (thread_)
271 thread_->WakeUp(); 286 thread_->WakeUp();
272 }
273 }
274
275 SchedulerWorker::SchedulerWorker(
276 ThreadPriority priority_hint,
277 std::unique_ptr<Delegate> delegate,
278 TaskTracker* task_tracker,
279 SchedulerBackwardCompatibility backward_compatibility)
280 : priority_hint_(priority_hint),
281 delegate_(std::move(delegate)),
282 task_tracker_(task_tracker)
283 #if defined(OS_WIN)
284 ,
285 backward_compatibility_(backward_compatibility)
286 #endif
287 {
288 DCHECK(delegate_);
289 DCHECK(task_tracker_);
290 } 287 }
291 288
292 SchedulerWorker::~SchedulerWorker() { 289 SchedulerWorker::~SchedulerWorker() {
293 // It is unexpected for |thread_| to be alive and for SchedulerWorker to 290 // It is unexpected for |thread_| to be alive and for SchedulerWorker to
294 // destroy since SchedulerWorker owns the delegate needed by |thread_|. 291 // destroy since SchedulerWorker owns the delegate needed by |thread_|.
295 // For testing, this generally means JoinForTesting was not called. 292 // For testing, this generally means JoinForTesting was not called.
296 DCHECK(!thread_); 293 DCHECK(!thread_);
297 } 294 }
298 295
299 std::unique_ptr<SchedulerWorker::Thread> SchedulerWorker::DetachThreadObject( 296 std::unique_ptr<SchedulerWorker::Thread> SchedulerWorker::DetachThreadObject(
(...skipping 15 matching lines...) Expand all
315 if (detach_notify == DetachNotify::DELEGATE) { 312 if (detach_notify == DetachNotify::DELEGATE) {
316 // Call OnDetach() within the scope of |thread_lock_| to prevent the 313 // Call OnDetach() within the scope of |thread_lock_| to prevent the
317 // delegate from being used concurrently from an old and a new thread. 314 // delegate from being used concurrently from an old and a new thread.
318 delegate_->OnDetach(); 315 delegate_->OnDetach();
319 } 316 }
320 317
321 return std::move(thread_); 318 return std::move(thread_);
322 } 319 }
323 320
324 void SchedulerWorker::CreateThread() { 321 void SchedulerWorker::CreateThread() {
325 thread_ = Thread::Create(make_scoped_refptr(this));
326 }
327
328 void SchedulerWorker::CreateThreadAssertSynchronized() {
329 thread_lock_.AssertAcquired(); 322 thread_lock_.AssertAcquired();
330 CreateThread(); 323 if (started_)
324 thread_ = Thread::Create(make_scoped_refptr(this));
331 } 325 }
332 326
333 bool SchedulerWorker::ShouldExit() { 327 bool SchedulerWorker::ShouldExit() {
334 // The ordering of the checks is important below. This SchedulerWorker may be 328 // The ordering of the checks is important below. This SchedulerWorker may be
335 // released and outlive |task_tracker_| in unit tests. However, when the 329 // released and outlive |task_tracker_| in unit tests. However, when the
336 // SchedulerWorker is released, |should_exit_| will be set, so check that 330 // SchedulerWorker is released, |should_exit_| will be set, so check that
337 // first. 331 // first.
338 return should_exit_.IsSet() || join_called_for_testing_.IsSet() || 332 return should_exit_.IsSet() || join_called_for_testing_.IsSet() ||
339 task_tracker_->IsShutdownComplete(); 333 task_tracker_->IsShutdownComplete();
340 } 334 }
341 335
342 } // namespace internal 336 } // namespace internal
343 } // namespace base 337 } // namespace base
OLDNEW
« no previous file with comments | « base/task_scheduler/scheduler_worker.h ('k') | base/task_scheduler/scheduler_worker_pool_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698