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 |