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