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}
This commit is contained in:
Sebastian Jansson
2020-01-17 13:58:54 +01:00
committed by Commit Bot
parent db6ca7f2d7
commit 274cc7fadf
4 changed files with 42 additions and 0 deletions

View File

@ -81,8 +81,11 @@ void SimulatedThread::Send(const rtc::Location& posted_from,
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);
}
}

View File

@ -160,6 +160,15 @@ void SimulatedTimeControllerImpl::Unregister(SimulatedSequenceRunner* runner) {
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(

View File

@ -79,6 +79,11 @@ class SimulatedTimeControllerImpl : public TaskQueueFactory,
// 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();

View File

@ -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 @@ TEST(SimulatedTimeControllerTest, DelayTaskRunOnTime) {
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