blob: da675af81e79eb71045b068946a6573a2c933f36 [file] [log] [blame]
Sebastian Jansson53cd9e22020-01-13 10:33:19 +01001/*
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
15namespace webrtc {
16
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
24SimulatedTaskQueue::~SimulatedTaskQueue() {
25 handler_->Unregister(this);
26 delete[] name_;
27}
28
29void SimulatedTaskQueue::Delete() {
Markus Handell563d4972020-07-08 15:56:14 +020030 // 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;
Sebastian Jansson53cd9e22020-01-13 10:33:19 +010034 {
Markus Handelle56976d2020-07-08 17:34:37 +020035 MutexLock lock(&lock_);
Markus Handell563d4972020-07-08 15:56:14 +020036 ready_tasks_.swap(ready_tasks);
37 delayed_tasks_.swap(delayed_tasks);
Sebastian Jansson53cd9e22020-01-13 10:33:19 +010038 }
Markus Handell563d4972020-07-08 15:56:14 +020039 ready_tasks.clear();
40 delayed_tasks.clear();
Sebastian Jansson53cd9e22020-01-13 10:33:19 +010041 delete this;
42}
43
44void SimulatedTaskQueue::RunReady(Timestamp at_time) {
Markus Handelle56976d2020-07-08 17:34:37 +020045 MutexLock lock(&lock_);
Sebastian Jansson53cd9e22020-01-13 10:33:19 +010046 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();
Markus Handelle56976d2020-07-08 17:34:37 +020057 lock_.Unlock();
Sebastian Jansson53cd9e22020-01-13 10:33:19 +010058 bool delete_task = ready->Run();
59 if (delete_task) {
60 ready.reset();
61 } else {
62 ready.release();
63 }
Markus Handelle56976d2020-07-08 17:34:37 +020064 lock_.Lock();
Sebastian Jansson53cd9e22020-01-13 10:33:19 +010065 }
66 if (!delayed_tasks_.empty()) {
67 next_run_time_ = delayed_tasks_.begin()->first;
68 } else {
69 next_run_time_ = Timestamp::PlusInfinity();
70 }
71}
72
73void SimulatedTaskQueue::PostTask(std::unique_ptr<QueuedTask> task) {
Markus Handelle56976d2020-07-08 17:34:37 +020074 MutexLock lock(&lock_);
Sebastian Jansson53cd9e22020-01-13 10:33:19 +010075 ready_tasks_.emplace_back(std::move(task));
76 next_run_time_ = Timestamp::MinusInfinity();
77}
78
79void SimulatedTaskQueue::PostDelayedTask(std::unique_ptr<QueuedTask> task,
80 uint32_t milliseconds) {
Markus Handelle56976d2020-07-08 17:34:37 +020081 MutexLock lock(&lock_);
Danil Chapovalov0c626af2020-02-10 11:16:00 +010082 Timestamp target_time =
83 handler_->CurrentTime() + TimeDelta::Millis(milliseconds);
Sebastian Jansson53cd9e22020-01-13 10:33:19 +010084 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