Always enter yield policy scope using simulated TimeControllers.

This makes the class easier to use at a minor cost of making it slightly
more magic.

Bug: webrtc:9883
Change-Id: If807cfbf046615333c3bcd3b58a001813102a9f9
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161231
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Markus Handell <handellm@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30008}
This commit is contained in:
Sebastian Jansson 2019-12-04 10:07:48 +01:00 committed by Commit Bot
parent 242a9e0ffe
commit 340af975e9
10 changed files with 11 additions and 61 deletions

View File

@ -40,12 +40,6 @@ class TimeController {
// Allow task queues and process threads created by this instance to execute
// for the given |duration|.
virtual void AdvanceTime(TimeDelta duration) = 0;
// Execute closure in an implementation defined scope where rtc::Event::Wait
// might yield to execute other tasks. This allows doing blocking waits on
// tasks on other task queues froma a task queue without deadlocking.
virtual void InvokeWithControlledYield(std::function<void()> closure) = 0;
// Returns a YieldInterface which can be installed as a ScopedYieldPolicy.
virtual rtc::YieldInterface* YieldInterface() = 0;
};
// Interface for telling time, scheduling an event to fire at a particular time,

View File

@ -321,8 +321,7 @@ void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
}
void CallClient::SendTask(std::function<void()> task) {
time_controller_->InvokeWithControlledYield(
[&] { task_queue_.SendTask(std::move(task), RTC_FROM_HERE); });
task_queue_.SendTask(std::move(task), RTC_FROM_HERE);
}
CallClientPair::~CallClientPair() = default;

View File

@ -159,7 +159,9 @@ class ExternalTimeController::TaskQueueWrapper : public TaskQueueBase {
};
ExternalTimeController::ExternalTimeController(ControlledAlarmClock* alarm)
: alarm_(alarm), impl_(alarm_->GetClock()->CurrentTime()) {
: alarm_(alarm),
impl_(alarm_->GetClock()->CurrentTime()),
yield_policy_(&impl_) {
global_clock_.SetTime(alarm_->GetClock()->CurrentTime());
alarm_->SetCallback([this] { Run(); });
}
@ -182,16 +184,6 @@ void ExternalTimeController::AdvanceTime(TimeDelta duration) {
alarm_->Sleep(duration);
}
void ExternalTimeController::InvokeWithControlledYield(
std::function<void()> closure) {
rtc::ScopedYieldPolicy policy(YieldInterface());
closure();
}
rtc::YieldInterface* ExternalTimeController::YieldInterface() {
return &impl_;
}
std::unique_ptr<TaskQueueBase, TaskQueueDeleter>
ExternalTimeController::CreateTaskQueue(
absl::string_view name,

View File

@ -38,8 +38,6 @@ class ExternalTimeController : public TimeController, public TaskQueueFactory {
std::unique_ptr<ProcessThread> CreateProcessThread(
const char* thread_name) override;
void AdvanceTime(TimeDelta duration) override;
void InvokeWithControlledYield(std::function<void()> closure) override;
rtc::YieldInterface* YieldInterface() override;
// Implementation of TaskQueueFactory.
std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
@ -59,6 +57,7 @@ class ExternalTimeController : public TimeController, public TaskQueueFactory {
ControlledAlarmClock* alarm_;
sim_time_impl::SimulatedTimeControllerImpl impl_;
rtc::ScopedYieldPolicy yield_policy_;
// Overrides the global rtc::Clock to ensure that it reports the same times as
// the time controller.

View File

@ -138,11 +138,9 @@ TEST(ExternalTimeControllerTest, YieldForTask) {
time_simulation.GetTaskQueueFactory()->CreateTaskQueue(
"TestQueue", TaskQueueFactory::Priority::NORMAL));
time_simulation.InvokeWithControlledYield([&] {
rtc::Event event;
task_queue.PostTask([&] { event.Set(); });
EXPECT_TRUE(event.Wait(200));
});
rtc::Event event;
task_queue.PostTask([&] { event.Set(); });
EXPECT_TRUE(event.Wait(200));
}
TEST(ExternalTimeControllerTest, TasksYieldToEachOther) {

View File

@ -34,15 +34,6 @@ void RealTimeController::AdvanceTime(TimeDelta duration) {
SleepMs(duration.ms());
}
void RealTimeController::InvokeWithControlledYield(
std::function<void()> closure) {
closure();
}
rtc::YieldInterface* RealTimeController::YieldInterface() {
return nullptr;
}
RealTimeController* GlobalRealTimeController() {
static RealTimeController* time_controller = new RealTimeController();
return time_controller;

View File

@ -29,8 +29,6 @@ class RealTimeController : public TimeController {
std::unique_ptr<ProcessThread> CreateProcessThread(
const char* thread_name) override;
void AdvanceTime(TimeDelta duration) override;
void InvokeWithControlledYield(std::function<void()> closure) override;
rtc::YieldInterface* YieldInterface() override;
private:
std::unique_ptr<TaskQueueFactory> task_queue_factory_;

View File

@ -399,7 +399,7 @@ void SimulatedTimeControllerImpl::Unregister(SimulatedSequenceRunner* runner) {
GlobalSimulatedTimeController::GlobalSimulatedTimeController(
Timestamp start_time)
: sim_clock_(start_time.us()), impl_(start_time) {
: sim_clock_(start_time.us()), impl_(start_time), yield_policy_(&impl_) {
global_clock_.SetTime(start_time);
}
@ -434,16 +434,4 @@ void GlobalSimulatedTimeController::AdvanceTime(TimeDelta duration) {
}
}
void GlobalSimulatedTimeController::InvokeWithControlledYield(
std::function<void()> closure) {
rtc::ScopedYieldPolicy yield_policy(&impl_);
closure();
}
rtc::YieldInterface* GlobalSimulatedTimeController::YieldInterface() {
return &impl_;
}
// namespace sim_time_impl
} // namespace webrtc

View File

@ -91,14 +91,13 @@ class GlobalSimulatedTimeController : public TimeController {
std::unique_ptr<ProcessThread> CreateProcessThread(
const char* thread_name) override;
void AdvanceTime(TimeDelta duration) override;
void InvokeWithControlledYield(std::function<void()> closure) override;
rtc::YieldInterface* YieldInterface() override;
private:
rtc::ScopedBaseFakeClock global_clock_;
// Provides simulated CurrentNtpInMilliseconds()
SimulatedClock sim_clock_;
sim_time_impl::SimulatedTimeControllerImpl impl_;
rtc::ScopedYieldPolicy yield_policy_;
};
} // namespace webrtc

View File

@ -493,26 +493,18 @@ class VideoReceiveStreamTestWithSimulatedClock : public ::testing::Test {
&call_stats_,
time_controller_.GetClock(),
new VCMTiming(time_controller_.GetClock())) {
time_controller_.InvokeWithControlledYield(
[this] { video_receive_stream_.Start(); });
}
~VideoReceiveStreamTestWithSimulatedClock() {
time_controller_.InvokeWithControlledYield(
[this] { video_receive_stream_.Stop(); });
video_receive_stream_.Start();
}
void OnFrameDecoded() { event_->Set(); }
void PassEncodedFrameAndWait(
std::unique_ptr<video_coding::EncodedFrame> frame) {
time_controller_.InvokeWithControlledYield([this, &frame] {
event_ = std::make_unique<rtc::Event>();
// This call will eventually end up in the Decoded method where the
// event is set.
video_receive_stream_.OnCompleteFrame(std::move(frame));
event_->Wait(rtc::Event::kForever);
});
}
protected: