blob: 66b3fd808753488edeb964ef82386b465f910a3f [file] [log] [blame]
Sebastian Jansson53cd9e22020-01-13 09:33:191/*
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 13:56:1430 // Need to destroy the tasks outside of the lock because task destruction
31 // can lead to re-entry in SimulatedTaskQueue via custom destructors.
Danil Chapovalov9c125c62022-07-07 18:29:3032 std::deque<absl::AnyInvocable<void() &&>> ready_tasks;
33 std::map<Timestamp, std::vector<absl::AnyInvocable<void() &&>>> delayed_tasks;
Sebastian Jansson53cd9e22020-01-13 09:33:1934 {
Markus Handelle56976d2020-07-08 15:34:3735 MutexLock lock(&lock_);
Markus Handell563d4972020-07-08 13:56:1436 ready_tasks_.swap(ready_tasks);
37 delayed_tasks_.swap(delayed_tasks);
Sebastian Jansson53cd9e22020-01-13 09:33:1938 }
Markus Handell563d4972020-07-08 13:56:1439 ready_tasks.clear();
40 delayed_tasks.clear();
Sebastian Jansson53cd9e22020-01-13 09:33:1941 delete this;
42}
43
44void SimulatedTaskQueue::RunReady(Timestamp at_time) {
Markus Handelle56976d2020-07-08 15:34:3745 MutexLock lock(&lock_);
Sebastian Jansson53cd9e22020-01-13 09:33:1946 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) {
Danil Chapovalov9c125c62022-07-07 18:29:3050 ready_tasks_.push_back(std::move(task));
Sebastian Jansson53cd9e22020-01-13 09:33:1951 }
52 }
53 CurrentTaskQueueSetter set_current(this);
54 while (!ready_tasks_.empty()) {
Danil Chapovalov9c125c62022-07-07 18:29:3055 absl::AnyInvocable<void()&&> ready = std::move(ready_tasks_.front());
Sebastian Jansson53cd9e22020-01-13 09:33:1956 ready_tasks_.pop_front();
Markus Handelle56976d2020-07-08 15:34:3757 lock_.Unlock();
Danil Chapovalov9c125c62022-07-07 18:29:3058 std::move(ready)();
59 ready = nullptr;
Markus Handelle56976d2020-07-08 15:34:3760 lock_.Lock();
Sebastian Jansson53cd9e22020-01-13 09:33:1961 }
62 if (!delayed_tasks_.empty()) {
63 next_run_time_ = delayed_tasks_.begin()->first;
64 } else {
65 next_run_time_ = Timestamp::PlusInfinity();
66 }
67}
68
Markus Handella1ceae22023-03-01 09:13:2869void SimulatedTaskQueue::PostTaskImpl(absl::AnyInvocable<void() &&> task,
70 const PostTaskTraits& /*traits*/,
71 const Location& /*location*/) {
Markus Handelle56976d2020-07-08 15:34:3772 MutexLock lock(&lock_);
Danil Chapovalov9c125c62022-07-07 18:29:3073 ready_tasks_.push_back(std::move(task));
Sebastian Jansson53cd9e22020-01-13 09:33:1974 next_run_time_ = Timestamp::MinusInfinity();
75}
76
Markus Handella1ceae22023-03-01 09:13:2877void SimulatedTaskQueue::PostDelayedTaskImpl(
Danil Chapovalov9c125c62022-07-07 18:29:3078 absl::AnyInvocable<void() &&> task,
Markus Handella1ceae22023-03-01 09:13:2879 TimeDelta delay,
80 const PostDelayedTaskTraits& /*traits*/,
81 const Location& /*location*/) {
Markus Handelle56976d2020-07-08 15:34:3782 MutexLock lock(&lock_);
Mirko Bonadei3b205da2022-08-09 08:24:1783 Timestamp target_time = handler_->CurrentTime() + delay;
Sebastian Jansson53cd9e22020-01-13 09:33:1984 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