1 /* 2 * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 #include "test/time_controller/simulated_task_queue.h" 11 12 #include <algorithm> 13 #include <utility> 14 15 namespace webrtc { 16 SimulatedTaskQueue(sim_time_impl::SimulatedTimeControllerImpl * handler,absl::string_view name)17SimulatedTaskQueue::SimulatedTaskQueue( 18 sim_time_impl::SimulatedTimeControllerImpl* handler, 19 absl::string_view name) 20 : handler_(handler), name_(new char[name.size()]) { 21 std::copy_n(name.begin(), name.size(), name_); 22 } 23 ~SimulatedTaskQueue()24SimulatedTaskQueue::~SimulatedTaskQueue() { 25 handler_->Unregister(this); 26 delete[] name_; 27 } 28 Delete()29void SimulatedTaskQueue::Delete() { 30 // Need to destroy the tasks outside of the lock because task destruction 31 // can lead to re-entry in SimulatedTaskQueue via custom destructors. 32 std::deque<std::unique_ptr<QueuedTask>> ready_tasks; 33 std::map<Timestamp, std::vector<std::unique_ptr<QueuedTask>>> delayed_tasks; 34 { 35 MutexLock lock(&lock_); 36 ready_tasks_.swap(ready_tasks); 37 delayed_tasks_.swap(delayed_tasks); 38 } 39 ready_tasks.clear(); 40 delayed_tasks.clear(); 41 delete this; 42 } 43 RunReady(Timestamp at_time)44void SimulatedTaskQueue::RunReady(Timestamp at_time) { 45 MutexLock lock(&lock_); 46 for (auto it = delayed_tasks_.begin(); 47 it != delayed_tasks_.end() && it->first <= at_time; 48 it = delayed_tasks_.erase(it)) { 49 for (auto& task : it->second) { 50 ready_tasks_.emplace_back(std::move(task)); 51 } 52 } 53 CurrentTaskQueueSetter set_current(this); 54 while (!ready_tasks_.empty()) { 55 std::unique_ptr<QueuedTask> ready = std::move(ready_tasks_.front()); 56 ready_tasks_.pop_front(); 57 lock_.Unlock(); 58 bool delete_task = ready->Run(); 59 if (delete_task) { 60 ready.reset(); 61 } else { 62 ready.release(); 63 } 64 lock_.Lock(); 65 } 66 if (!delayed_tasks_.empty()) { 67 next_run_time_ = delayed_tasks_.begin()->first; 68 } else { 69 next_run_time_ = Timestamp::PlusInfinity(); 70 } 71 } 72 PostTask(std::unique_ptr<QueuedTask> task)73void SimulatedTaskQueue::PostTask(std::unique_ptr<QueuedTask> task) { 74 MutexLock lock(&lock_); 75 ready_tasks_.emplace_back(std::move(task)); 76 next_run_time_ = Timestamp::MinusInfinity(); 77 } 78 PostDelayedTask(std::unique_ptr<QueuedTask> task,uint32_t milliseconds)79void SimulatedTaskQueue::PostDelayedTask(std::unique_ptr<QueuedTask> task, 80 uint32_t milliseconds) { 81 MutexLock lock(&lock_); 82 Timestamp target_time = 83 handler_->CurrentTime() + TimeDelta::Millis(milliseconds); 84 delayed_tasks_[target_time].push_back(std::move(task)); 85 next_run_time_ = std::min(next_run_time_, target_time); 86 } 87 88 } // namespace webrtc 89