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

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

Issue 2806413002: Separate the create and start phases in SchedulerSingleThreadTaskRunnerManager. (Closed)
Patch Set: self-review 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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_single_thread_task_runner_manager.h" 5 #include "base/task_scheduler/scheduler_single_thread_task_runner_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 ~SchedulerSingleThreadTaskRunnerManager() { 333 ~SchedulerSingleThreadTaskRunnerManager() {
334 #if DCHECK_IS_ON() 334 #if DCHECK_IS_ON()
335 size_t workers_unregistered_during_join = 335 size_t workers_unregistered_during_join =
336 subtle::NoBarrier_Load(&workers_unregistered_during_join_); 336 subtle::NoBarrier_Load(&workers_unregistered_during_join_);
337 DCHECK_EQ(workers_unregistered_during_join, workers_.size()) 337 DCHECK_EQ(workers_unregistered_during_join, workers_.size())
338 << "There cannot be outstanding SingleThreadTaskRunners upon destruction " 338 << "There cannot be outstanding SingleThreadTaskRunners upon destruction "
339 "of SchedulerSingleThreadTaskRunnerManager or the Task Scheduler"; 339 "of SchedulerSingleThreadTaskRunnerManager or the Task Scheduler";
340 #endif 340 #endif
341 } 341 }
342 342
343 void SchedulerSingleThreadTaskRunnerManager::Start() {
344 decltype(workers_) workers_to_start;
345 {
346 AutoSchedulerLock auto_lock(lock_);
347 started_ = true;
348 workers_to_start = workers_;
349 }
350
351 // Start workers that were created before this method was called. Other
352 // workers are started as they are created.
353 for (scoped_refptr<SchedulerWorker> worker : workers_to_start) {
354 worker->Start();
355 worker->WakeUp();
356 }
357 }
358
343 scoped_refptr<SingleThreadTaskRunner> 359 scoped_refptr<SingleThreadTaskRunner>
344 SchedulerSingleThreadTaskRunnerManager::CreateSingleThreadTaskRunnerWithTraits( 360 SchedulerSingleThreadTaskRunnerManager::CreateSingleThreadTaskRunnerWithTraits(
345 const TaskTraits& traits) { 361 const TaskTraits& traits) {
346 return CreateSingleThreadTaskRunnerWithDelegate<SchedulerWorkerDelegate>( 362 return CreateSingleThreadTaskRunnerWithDelegate<SchedulerWorkerDelegate>(
347 traits); 363 traits);
348 } 364 }
349 365
350 #if defined(OS_WIN) 366 #if defined(OS_WIN)
351 scoped_refptr<SingleThreadTaskRunner> 367 scoped_refptr<SingleThreadTaskRunner>
352 SchedulerSingleThreadTaskRunnerManager::CreateCOMSTATaskRunnerWithTraits( 368 SchedulerSingleThreadTaskRunnerManager::CreateCOMSTATaskRunnerWithTraits(
353 const TaskTraits& traits) { 369 const TaskTraits& traits) {
354 return CreateSingleThreadTaskRunnerWithDelegate<SchedulerWorkerCOMDelegate>( 370 return CreateSingleThreadTaskRunnerWithDelegate<SchedulerWorkerCOMDelegate>(
355 traits); 371 traits);
356 } 372 }
357 #endif // defined(OS_WIN) 373 #endif // defined(OS_WIN)
358 374
359 void SchedulerSingleThreadTaskRunnerManager::JoinForTesting() { 375 void SchedulerSingleThreadTaskRunnerManager::JoinForTesting() {
360 decltype(workers_) local_workers; 376 decltype(workers_) local_workers;
361 { 377 {
362 AutoSchedulerLock auto_lock(workers_lock_); 378 AutoSchedulerLock auto_lock(lock_);
363 local_workers = std::move(workers_); 379 local_workers = std::move(workers_);
364 } 380 }
365 381
366 for (const auto& worker : local_workers) 382 for (const auto& worker : local_workers)
367 worker->JoinForTesting(); 383 worker->JoinForTesting();
368 384
369 { 385 {
370 AutoSchedulerLock auto_lock(workers_lock_); 386 AutoSchedulerLock auto_lock(lock_);
371 DCHECK(workers_.empty()) 387 DCHECK(workers_.empty())
372 << "New worker(s) unexpectedly registered during join."; 388 << "New worker(s) unexpectedly registered during join.";
373 workers_ = std::move(local_workers); 389 workers_ = std::move(local_workers);
374 } 390 }
375 } 391 }
376 392
377 template <typename DelegateType> 393 template <typename DelegateType>
378 scoped_refptr<SingleThreadTaskRunner> SchedulerSingleThreadTaskRunnerManager:: 394 scoped_refptr<SingleThreadTaskRunner> SchedulerSingleThreadTaskRunnerManager::
379 CreateSingleThreadTaskRunnerWithDelegate(const TaskTraits& traits) { 395 CreateSingleThreadTaskRunnerWithDelegate(const TaskTraits& traits) {
380 size_t index = worker_pool_index_for_traits_callback_.Run(traits); 396 size_t index = worker_pool_index_for_traits_callback_.Run(traits);
(...skipping 22 matching lines...) Expand all
403 StringPrintf("TaskSchedulerSingleThreadWorker%d%sCOMSTA", id, 419 StringPrintf("TaskSchedulerSingleThreadWorker%d%sCOMSTA", id,
404 params.name().c_str()), 420 params.name().c_str()),
405 task_tracker_); 421 task_tracker_);
406 } 422 }
407 #endif // defined(OS_WIN) 423 #endif // defined(OS_WIN)
408 424
409 template <typename DelegateType> 425 template <typename DelegateType>
410 SchedulerWorker* 426 SchedulerWorker*
411 SchedulerSingleThreadTaskRunnerManager::CreateAndRegisterSchedulerWorker( 427 SchedulerSingleThreadTaskRunnerManager::CreateAndRegisterSchedulerWorker(
412 const SchedulerWorkerPoolParams& params) { 428 const SchedulerWorkerPoolParams& params) {
413 AutoSchedulerLock auto_lock(workers_lock_); 429 SchedulerWorker* worker;
414 int id = next_worker_id_++; 430 bool start_worker;
415 431
416 workers_.emplace_back(SchedulerWorker::Create( 432 {
417 params.priority_hint(), 433 AutoSchedulerLock auto_lock(lock_);
418 CreateSchedulerWorkerDelegate<DelegateType>(params, id), task_tracker_, 434 int id = next_worker_id_++;
419 SchedulerWorker::InitialState::DETACHED)); 435 workers_.emplace_back(make_scoped_refptr(new SchedulerWorker(
420 return workers_.back().get(); 436 params.priority_hint(),
437 CreateSchedulerWorkerDelegate<DelegateType>(params, id),
438 task_tracker_)));
439 worker = workers_.back().get();
440 start_worker = started_;
441 }
442
443 if (start_worker)
444 worker->Start();
445
446 return worker;
421 } 447 }
422 448
423 void SchedulerSingleThreadTaskRunnerManager::UnregisterSchedulerWorker( 449 void SchedulerSingleThreadTaskRunnerManager::UnregisterSchedulerWorker(
424 SchedulerWorker* worker) { 450 SchedulerWorker* worker) {
425 // Cleanup uses a SchedulerLock, so call Cleanup() after releasing 451 // Cleanup uses a SchedulerLock, so call Cleanup() after releasing
426 // |workers_lock_|. 452 // |lock_|.
427 scoped_refptr<SchedulerWorker> worker_to_destroy; 453 scoped_refptr<SchedulerWorker> worker_to_destroy;
428 { 454 {
429 AutoSchedulerLock auto_lock(workers_lock_); 455 AutoSchedulerLock auto_lock(lock_);
430 456
431 // We might be joining, so record that a worker was unregistered for 457 // We might be joining, so record that a worker was unregistered for
432 // verification at destruction. 458 // verification at destruction.
433 if (workers_.empty()) { 459 if (workers_.empty()) {
434 #if DCHECK_IS_ON() 460 #if DCHECK_IS_ON()
435 subtle::NoBarrier_AtomicIncrement(&workers_unregistered_during_join_, 1); 461 subtle::NoBarrier_AtomicIncrement(&workers_unregistered_during_join_, 1);
436 #endif 462 #endif
437 return; 463 return;
438 } 464 }
439 465
440 auto worker_iter = 466 auto worker_iter =
441 std::find_if(workers_.begin(), workers_.end(), 467 std::find_if(workers_.begin(), workers_.end(),
442 [worker](const scoped_refptr<SchedulerWorker>& candidate) { 468 [worker](const scoped_refptr<SchedulerWorker>& candidate) {
443 return candidate.get() == worker; 469 return candidate.get() == worker;
444 }); 470 });
445 DCHECK(worker_iter != workers_.end()); 471 DCHECK(worker_iter != workers_.end());
446 worker_to_destroy = std::move(*worker_iter); 472 worker_to_destroy = std::move(*worker_iter);
447 workers_.erase(worker_iter); 473 workers_.erase(worker_iter);
448 } 474 }
449 worker_to_destroy->Cleanup(); 475 worker_to_destroy->Cleanup();
450 } 476 }
451 477
452 } // namespace internal 478 } // namespace internal
453 } // namespace base 479 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698