coalesced_tasks.cc 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "third_party/webrtc_overrides/coalesced_tasks.h"
  5. #include <vector>
  6. namespace blink {
  7. CoalescedTasks::UniqueTimeTicks::UniqueTimeTicks(base::TimeTicks time_ticks,
  8. uint64_t unique_id)
  9. : time_ticks(std::move(time_ticks)), unique_id(unique_id) {}
  10. bool CoalescedTasks::UniqueTimeTicks::operator<(
  11. const UniqueTimeTicks& other) const {
  12. if (time_ticks < other.time_ticks)
  13. return true;
  14. if (time_ticks == other.time_ticks)
  15. return unique_id < other.unique_id;
  16. return false;
  17. }
  18. bool CoalescedTasks::QueueDelayedTask(base::TimeTicks task_time,
  19. absl::AnyInvocable<void() &&> task,
  20. base::TimeTicks scheduled_time) {
  21. DCHECK_GE(scheduled_time, task_time);
  22. base::AutoLock auto_lock(lock_);
  23. bool is_new_schedule_time = scheduled_ticks_.insert(scheduled_time).second;
  24. delayed_tasks_.insert(std::make_pair(
  25. UniqueTimeTicks(task_time, next_unique_id_++), std::move(task)));
  26. return is_new_schedule_time;
  27. }
  28. CoalescedTasks::~CoalescedTasks() {
  29. DCHECK(delayed_tasks_.empty());
  30. }
  31. void CoalescedTasks::RunScheduledTasks(
  32. base::TimeTicks scheduled_time,
  33. PrepareRunTaskCallback prepare_run_task_callback,
  34. FinalizeRunTaskCallback finalize_run_task_callback) {
  35. std::vector<absl::AnyInvocable<void() &&>> ready_tasks;
  36. {
  37. base::AutoLock auto_lock(lock_);
  38. // `scheduled_time` is no longer scheduled.
  39. auto scheduled_ticks_it = scheduled_ticks_.find(scheduled_time);
  40. DCHECK(scheduled_ticks_it != scheduled_ticks_.end());
  41. scheduled_ticks_.erase(scheduled_ticks_it);
  42. // Obtain ready tasks so that we can run them whilst not holding the lock.
  43. while (!delayed_tasks_.empty()) {
  44. // `delayed_tasks_` is ordered, so the first element is the earliest task.
  45. auto first_delayed_task_it = delayed_tasks_.begin();
  46. if (first_delayed_task_it->first.time_ticks > scheduled_time) {
  47. // The remaining tasks are not ready yet.
  48. break;
  49. }
  50. ready_tasks.push_back(std::move(first_delayed_task_it->second));
  51. delayed_tasks_.erase(first_delayed_task_it);
  52. }
  53. }
  54. // Run ready tasks.
  55. for (auto& ready_task : ready_tasks) {
  56. absl::optional<base::TimeTicks> task_start_timestamp;
  57. if (prepare_run_task_callback) {
  58. task_start_timestamp = prepare_run_task_callback.Run();
  59. }
  60. std::move(ready_task)();
  61. if (finalize_run_task_callback) {
  62. finalize_run_task_callback.Run(std::move(task_start_timestamp));
  63. }
  64. }
  65. }
  66. void CoalescedTasks::Clear() {
  67. base::AutoLock auto_lock(lock_);
  68. scheduled_ticks_.clear();
  69. delayed_tasks_.clear();
  70. }
  71. } // namespace blink