Adds current thread to yielders in SimulatedThread::SendTask.
Bug: webrtc:11255
Change-Id: Ib65b902b60b15f402fac51269c74ac46b56cabc5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/166462
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30304}
diff --git a/test/time_controller/simulated_thread.cc b/test/time_controller/simulated_thread.cc
index 8d82ebd..937fe32 100644
--- a/test/time_controller/simulated_thread.cc
+++ b/test/time_controller/simulated_thread.cc
@@ -81,8 +81,11 @@
if (IsCurrent()) {
msg.phandler->OnMessage(&msg);
} else {
+ TaskQueueBase* yielding_from = TaskQueueBase::Current();
+ handler_->StartYield(yielding_from);
CurrentThreadSetter set_current(this);
msg.phandler->OnMessage(&msg);
+ handler_->StopYield(yielding_from);
}
}
diff --git a/test/time_controller/simulated_time_controller.cc b/test/time_controller/simulated_time_controller.cc
index d3bc66a..a81083b 100644
--- a/test/time_controller/simulated_time_controller.cc
+++ b/test/time_controller/simulated_time_controller.cc
@@ -160,6 +160,15 @@
RTC_CHECK(removed);
RemoveByValue(&ready_runners_, runner);
}
+
+void SimulatedTimeControllerImpl::StartYield(TaskQueueBase* yielding_from) {
+ auto inserted = yielded_.insert(yielding_from);
+ RTC_DCHECK(inserted.second);
+}
+
+void SimulatedTimeControllerImpl::StopYield(TaskQueueBase* yielding_from) {
+ yielded_.erase(yielding_from);
+}
} // namespace sim_time_impl
GlobalSimulatedTimeController::GlobalSimulatedTimeController(
diff --git a/test/time_controller/simulated_time_controller.h b/test/time_controller/simulated_time_controller.h
index 783edb2..758f909 100644
--- a/test/time_controller/simulated_time_controller.h
+++ b/test/time_controller/simulated_time_controller.h
@@ -79,6 +79,11 @@
// Removes |runner| from |runners_|.
void Unregister(SimulatedSequenceRunner* runner);
+ // Indicates that |yielding_from| is not ready to run.
+ void StartYield(TaskQueueBase* yielding_from);
+ // Indicates that processing can be continued on |yielding_from|.
+ void StopYield(TaskQueueBase* yielding_from);
+
private:
const rtc::PlatformThreadId thread_id_;
const std::unique_ptr<rtc::Thread> dummy_thread_ = rtc::Thread::Create();
diff --git a/test/time_controller/simulated_time_controller_unittest.cc b/test/time_controller/simulated_time_controller_unittest.cc
index 469d2d7..2fe4bd2 100644
--- a/test/time_controller/simulated_time_controller_unittest.cc
+++ b/test/time_controller/simulated_time_controller_unittest.cc
@@ -18,6 +18,8 @@
#include "test/gmock.h"
#include "test/gtest.h"
+#include "rtc_base/event.h"
+
// NOTE: Since these tests rely on real time behavior, they will be flaky
// if run on heavily loaded systems.
namespace webrtc {
@@ -124,4 +126,27 @@
time_simulation.AdvanceTime(TimeDelta::ms(10));
EXPECT_TRUE(delay_task_executed);
}
+
+TEST(SimulatedTimeControllerTest, ThreadYeildsOnInvoke) {
+ GlobalSimulatedTimeController sim(kStartTime);
+ auto main_thread = sim.GetMainThread();
+ auto t2 = sim.CreateThread("thread", nullptr);
+ bool task_has_run = false;
+ // Posting a task to the main thread, this should not run until AdvanceTime is
+ // called.
+ main_thread->PostTask(RTC_FROM_HERE, [&] { task_has_run = true; });
+ t2->Invoke<void>(RTC_FROM_HERE, [] {
+ rtc::Event yield_event;
+ // Wait() triggers YieldExecution() which will runs message processing on
+ // all threads that are not in the yielded set.
+
+ yield_event.Wait(0);
+ });
+ // Since we are doing an invoke from the main thread, we don't expect the main
+ // thread message loop to be processed.
+ EXPECT_FALSE(task_has_run);
+ sim.AdvanceTime(TimeDelta::seconds(1));
+ ASSERT_TRUE(task_has_run);
+}
+
} // namespace webrtc