| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |