xref: /aosp_15_r20/external/webrtc/test/time_controller/simulated_thread.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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_thread.h"
11 
12 #include <algorithm>
13 #include <utility>
14 
15 namespace webrtc {
16 namespace {
17 
18 // A socket server that does nothing. It's different from NullSocketServer in
19 // that it does allow sleep/wakeup. This avoids usage of an Event instance which
20 // otherwise would cause issues with the simulated Yeild behavior.
21 class DummySocketServer : public rtc::SocketServer {
22  public:
CreateSocket(int family,int type)23   rtc::Socket* CreateSocket(int family, int type) override {
24     RTC_DCHECK_NOTREACHED();
25     return nullptr;
26   }
Wait(TimeDelta max_wait_duration,bool process_io)27   bool Wait(TimeDelta max_wait_duration, bool process_io) override {
28     RTC_CHECK(max_wait_duration.IsZero());
29     return true;
30   }
WakeUp()31   void WakeUp() override {}
32 };
33 
34 }  // namespace
35 
SimulatedThread(sim_time_impl::SimulatedTimeControllerImpl * handler,absl::string_view name,std::unique_ptr<rtc::SocketServer> socket_server)36 SimulatedThread::SimulatedThread(
37     sim_time_impl::SimulatedTimeControllerImpl* handler,
38     absl::string_view name,
39     std::unique_ptr<rtc::SocketServer> socket_server)
40     : rtc::Thread(socket_server ? std::move(socket_server)
41                                 : std::make_unique<DummySocketServer>()),
42       handler_(handler),
43       name_(new char[name.size()]) {
44   std::copy_n(name.begin(), name.size(), name_);
45 }
46 
~SimulatedThread()47 SimulatedThread::~SimulatedThread() {
48   handler_->Unregister(this);
49   delete[] name_;
50 }
51 
RunReady(Timestamp at_time)52 void SimulatedThread::RunReady(Timestamp at_time) {
53   CurrentThreadSetter set_current(this);
54   ProcessMessages(0);
55   int delay_ms = GetDelay();
56   MutexLock lock(&lock_);
57   if (delay_ms == kForever) {
58     next_run_time_ = Timestamp::PlusInfinity();
59   } else {
60     next_run_time_ = at_time + TimeDelta::Millis(delay_ms);
61   }
62 }
63 
BlockingCall(rtc::FunctionView<void ()> functor)64 void SimulatedThread::BlockingCall(rtc::FunctionView<void()> functor) {
65   if (IsQuitting())
66     return;
67 
68   if (IsCurrent()) {
69     functor();
70   } else {
71     TaskQueueBase* yielding_from = TaskQueueBase::Current();
72     handler_->StartYield(yielding_from);
73     RunReady(Timestamp::MinusInfinity());
74     CurrentThreadSetter set_current(this);
75     functor();
76     handler_->StopYield(yielding_from);
77   }
78 }
79 
PostTask(absl::AnyInvocable<void ()&&> task)80 void SimulatedThread::PostTask(absl::AnyInvocable<void() &&> task) {
81   rtc::Thread::PostTask(std::move(task));
82   MutexLock lock(&lock_);
83   next_run_time_ = Timestamp::MinusInfinity();
84 }
85 
PostDelayedTask(absl::AnyInvocable<void ()&&> task,TimeDelta delay)86 void SimulatedThread::PostDelayedTask(absl::AnyInvocable<void() &&> task,
87                                       TimeDelta delay) {
88   rtc::Thread::PostDelayedTask(std::move(task), delay);
89   MutexLock lock(&lock_);
90   next_run_time_ =
91       std::min(next_run_time_, Timestamp::Millis(rtc::TimeMillis()) + delay);
92 }
93 
PostDelayedHighPrecisionTask(absl::AnyInvocable<void ()&&> task,TimeDelta delay)94 void SimulatedThread::PostDelayedHighPrecisionTask(
95     absl::AnyInvocable<void() &&> task,
96     TimeDelta delay) {
97   rtc::Thread::PostDelayedHighPrecisionTask(std::move(task), delay);
98   MutexLock lock(&lock_);
99   next_run_time_ =
100       std::min(next_run_time_, Timestamp::Millis(rtc::TimeMillis()) + delay);
101 }
102 
Stop()103 void SimulatedThread::Stop() {
104   Thread::Quit();
105 }
106 
SimulatedMainThread(sim_time_impl::SimulatedTimeControllerImpl * handler)107 SimulatedMainThread::SimulatedMainThread(
108     sim_time_impl::SimulatedTimeControllerImpl* handler)
109     : SimulatedThread(handler, "main", nullptr), current_setter_(this) {}
110 
~SimulatedMainThread()111 SimulatedMainThread::~SimulatedMainThread() {
112   // Removes pending tasks in case they keep shared pointer references to
113   // objects whose destructor expects to run before the Thread destructor.
114   Stop();
115   DoDestroy();
116 }
117 
118 }  // namespace webrtc
119