Merge SendTask implementation for SingleThreadedTaskQueueForTesting and TaskQueueForTest

That allows to use SingleThreadedTaskQueueForTesting via TaskQueueBase interface
but still have access to test-only SendTask function.

Bug: webrtc:10933
Change-Id: I3cc397e55ea2f1ed9e5d885d6a2ccda412beb826
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/156002
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29480}
This commit is contained in:
Danil Chapovalov 2019-10-15 10:04:57 +02:00 committed by Commit Bot
parent 35214fcfe2
commit eb90e6ffe3
18 changed files with 773 additions and 668 deletions

View file

@ -552,7 +552,8 @@ TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
update.packet_loss_ratio = 0;
update.round_trip_time = TimeDelta::ms(50);
update.bwe_period = TimeDelta::ms(6000);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); });
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
}
TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) {
@ -565,7 +566,8 @@ TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) {
Eq(DataRate::bps(helper.config().max_bitrate_bps - 5000)))));
BitrateAllocationUpdate update;
update.target_bitrate = DataRate::bps(helper.config().max_bitrate_bps - 5000);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); });
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
}
TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) {
@ -580,7 +582,8 @@ TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) {
Eq(DataRate::kbps(6)))));
BitrateAllocationUpdate update;
update.target_bitrate = DataRate::kbps(1);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); });
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
}
TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) {
@ -595,7 +598,8 @@ TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) {
Eq(DataRate::kbps(64)))));
BitrateAllocationUpdate update;
update.target_bitrate = DataRate::kbps(128);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); });
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
}
TEST(AudioSendStreamTest, SSBweWithOverhead) {
@ -614,7 +618,8 @@ TEST(AudioSendStreamTest, SSBweWithOverhead) {
&BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
BitrateAllocationUpdate update;
update.target_bitrate = bitrate;
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); });
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
}
TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
@ -633,7 +638,8 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
&BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
BitrateAllocationUpdate update;
update.target_bitrate = DataRate::kbps(1);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); });
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
}
TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
@ -652,7 +658,8 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
&BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
BitrateAllocationUpdate update;
update.target_bitrate = DataRate::kbps(128);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); });
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
}
TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
@ -667,7 +674,8 @@ TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
update.packet_loss_ratio = 0;
update.round_trip_time = TimeDelta::ms(50);
update.bwe_period = TimeDelta::ms(5000);
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); });
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
RTC_FROM_HERE);
}
// Test that AudioSendStream doesn't recreate the encoder unnecessarily.

View file

@ -374,7 +374,8 @@ TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
TEST(AudioMixer, ConstructFromOtherThread) {
TaskQueueForTest init_queue("init");
rtc::scoped_refptr<AudioMixer> mixer;
init_queue.SendTask([&mixer]() { mixer = AudioMixerImpl::Create(); });
init_queue.SendTask([&mixer]() { mixer = AudioMixerImpl::Create(); },
RTC_FROM_HERE);
MockMixerAudioSource participant;
EXPECT_CALL(participant, PreferredSampleRate())
@ -384,7 +385,8 @@ TEST(AudioMixer, ConstructFromOtherThread) {
TaskQueueForTest participant_queue("participant");
participant_queue.SendTask(
[&mixer, &participant]() { mixer->AddSource(&participant); });
[&mixer, &participant]() { mixer->AddSource(&participant); },
RTC_FROM_HERE);
EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _))
.Times(Exactly(1));

View file

@ -447,7 +447,7 @@ void VideoCodecTestFixtureImpl::ProcessAllFrames(
}
// Wait until we know that the last frame has been sent for encode.
task_queue->SendTask([] {});
task_queue->SendTask([] {}, RTC_FROM_HERE);
// Give the VideoProcessor pipeline some time to process the last frame,
// and then release the codecs.
@ -686,22 +686,26 @@ void VideoCodecTestFixtureImpl::SetUpAndInitObjects(
cpu_process_time_.reset(new CpuProcessTime(config_));
task_queue->SendTask([this]() {
CreateEncoderAndDecoder();
processor_ = std::make_unique<VideoProcessor>(
encoder_.get(), &decoders_, source_frame_reader_.get(), config_,
&stats_, &encoded_frame_writers_,
decoded_frame_writers_.empty() ? nullptr : &decoded_frame_writers_);
});
task_queue->SendTask(
[this]() {
CreateEncoderAndDecoder();
processor_ = std::make_unique<VideoProcessor>(
encoder_.get(), &decoders_, source_frame_reader_.get(), config_,
&stats_, &encoded_frame_writers_,
decoded_frame_writers_.empty() ? nullptr : &decoded_frame_writers_);
},
RTC_FROM_HERE);
}
void VideoCodecTestFixtureImpl::ReleaseAndCloseObjects(
TaskQueueForTest* task_queue) {
task_queue->SendTask([this]() {
processor_.reset();
// The VideoProcessor must be destroyed before the codecs.
DestroyEncoderAndDecoder();
});
task_queue->SendTask(
[this]() {
processor_.reset();
// The VideoProcessor must be destroyed before the codecs.
DestroyEncoderAndDecoder();
},
RTC_FROM_HERE);
source_frame_reader_->Close();
@ -724,10 +728,12 @@ void VideoCodecTestFixtureImpl::PrintSettings(
RTC_LOG(LS_INFO) << "==> Codec names";
std::string encoder_name;
std::string decoder_name;
task_queue->SendTask([this, &encoder_name, &decoder_name] {
encoder_name = encoder_->GetEncoderInfo().implementation_name;
decoder_name = decoders_.at(0)->ImplementationName();
});
task_queue->SendTask(
[this, &encoder_name, &decoder_name] {
encoder_name = encoder_->GetEncoderInfo().implementation_name;
decoder_name = decoders_.at(0)->ImplementationName();
},
RTC_FROM_HERE);
RTC_LOG(LS_INFO) << "enc_impl_name: " << encoder_name;
RTC_LOG(LS_INFO) << "dec_impl_name: " << decoder_name;
}

View file

@ -54,15 +54,17 @@ class VideoProcessorTest : public ::testing::Test {
ExpectInit();
EXPECT_CALL(frame_reader_mock_, FrameLength())
.WillRepeatedly(Return(kFrameSize));
q_.SendTask([this] {
video_processor_ = std::make_unique<VideoProcessor>(
&encoder_mock_, &decoders_, &frame_reader_mock_, config_, &stats_,
&encoded_frame_writers_, /*decoded_frame_writers=*/nullptr);
});
q_.SendTask(
[this] {
video_processor_ = std::make_unique<VideoProcessor>(
&encoder_mock_, &decoders_, &frame_reader_mock_, config_, &stats_,
&encoded_frame_writers_, /*decoded_frame_writers=*/nullptr);
},
RTC_FROM_HERE);
}
~VideoProcessorTest() {
q_.SendTask([this] { video_processor_.reset(); });
q_.SendTask([this] { video_processor_.reset(); }, RTC_FROM_HERE);
}
void ExpectInit() {
@ -104,7 +106,8 @@ TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) {
SetRates(Field(&VideoEncoder::RateControlParameters::framerate_fps,
static_cast<double>(kFramerateFps))))
.Times(1);
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); });
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); },
RTC_FROM_HERE);
EXPECT_CALL(frame_reader_mock_, ReadFrame())
.WillRepeatedly(Return(I420Buffer::Create(kWidth, kHeight)));
@ -112,13 +115,13 @@ TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) {
encoder_mock_,
Encode(Property(&VideoFrame::timestamp, 1 * 90000 / kFramerateFps), _))
.Times(1);
q_.SendTask([this] { video_processor_->ProcessFrame(); });
q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
EXPECT_CALL(
encoder_mock_,
Encode(Property(&VideoFrame::timestamp, 2 * 90000 / kFramerateFps), _))
.Times(1);
q_.SendTask([this] { video_processor_->ProcessFrame(); });
q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
ExpectRelease();
}
@ -133,14 +136,15 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
static_cast<double>(kStartFramerateFps))))
.Times(1);
q_.SendTask(
[=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); });
[=] { video_processor_->SetRates(kBitrateKbps, kStartFramerateFps); },
RTC_FROM_HERE);
EXPECT_CALL(frame_reader_mock_, ReadFrame())
.WillRepeatedly(Return(I420Buffer::Create(kWidth, kHeight)));
EXPECT_CALL(encoder_mock_,
Encode(Property(&VideoFrame::timestamp, kStartTimestamp), _))
.Times(1);
q_.SendTask([this] { video_processor_->ProcessFrame(); });
q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
const int kNewFramerateFps = 13;
EXPECT_CALL(
@ -149,14 +153,15 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
static_cast<double>(kNewFramerateFps))))
.Times(1);
q_.SendTask(
[=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); });
[=] { video_processor_->SetRates(kBitrateKbps, kNewFramerateFps); },
RTC_FROM_HERE);
EXPECT_CALL(encoder_mock_,
Encode(Property(&VideoFrame::timestamp,
kStartTimestamp + 90000 / kNewFramerateFps),
_))
.Times(1);
q_.SendTask([this] { video_processor_->ProcessFrame(); });
q_.SendTask([this] { video_processor_->ProcessFrame(); }, RTC_FROM_HERE);
ExpectRelease();
}
@ -175,7 +180,8 @@ TEST_F(VideoProcessorTest, SetRates) {
Field(&VideoEncoder::RateControlParameters::framerate_fps,
static_cast<double>(kFramerateFps)))))
.Times(1);
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); });
q_.SendTask([=] { video_processor_->SetRates(kBitrateKbps, kFramerateFps); },
RTC_FROM_HERE);
const uint32_t kNewBitrateKbps = 456;
const int kNewFramerateFps = 34;
@ -190,7 +196,8 @@ TEST_F(VideoProcessorTest, SetRates) {
static_cast<double>(kNewFramerateFps)))))
.Times(1);
q_.SendTask(
[=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); });
[=] { video_processor_->SetRates(kNewBitrateKbps, kNewFramerateFps); },
RTC_FROM_HERE);
ExpectRelease();
}

View file

@ -71,15 +71,17 @@ class QualityScalerTest : public ::testing::Test,
: scoped_field_trial_(GetParam()),
task_queue_("QualityScalerTestQueue"),
observer_(new MockAdaptationObserver()) {
task_queue_.SendTask([this] {
qs_ = std::unique_ptr<QualityScaler>(new QualityScalerUnderTest(
&task_queue_, observer_.get(),
VideoEncoder::QpThresholds(kLowQp, kHighQp)));
});
task_queue_.SendTask(
[this] {
qs_ = std::unique_ptr<QualityScaler>(new QualityScalerUnderTest(
&task_queue_, observer_.get(),
VideoEncoder::QpThresholds(kLowQp, kHighQp)));
},
RTC_FROM_HERE);
}
~QualityScalerTest() {
task_queue_.SendTask([this] { qs_ = nullptr; });
task_queue_.SendTask([this] { qs_ = nullptr; }, RTC_FROM_HERE);
}
void TriggerScale(ScaleDirection scale_direction) {
@ -118,46 +120,52 @@ INSTANTIATE_TEST_SUITE_P(
""));
TEST_P(QualityScalerTest, DownscalesAfterContinuousFramedrop) {
task_queue_.SendTask([this] { TriggerScale(kScaleDown); });
task_queue_.SendTask([this] { TriggerScale(kScaleDown); }, RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_);
}
TEST_P(QualityScalerTest, KeepsScaleAtHighQp) {
task_queue_.SendTask([this] { TriggerScale(kKeepScaleAtHighQp); });
task_queue_.SendTask([this] { TriggerScale(kKeepScaleAtHighQp); },
RTC_FROM_HERE);
EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_);
}
TEST_P(QualityScalerTest, DownscalesAboveHighQp) {
task_queue_.SendTask([this] { TriggerScale(kScaleDownAboveHighQp); });
task_queue_.SendTask([this] { TriggerScale(kScaleDownAboveHighQp); },
RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_);
}
TEST_P(QualityScalerTest, DownscalesAfterTwoThirdsFramedrop) {
task_queue_.SendTask([this] {
for (int i = 0; i < kFramerate * 5; ++i) {
qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportQp(kHighQp, 0);
}
});
task_queue_.SendTask(
[this] {
for (int i = 0; i < kFramerate * 5; ++i) {
qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportQp(kHighQp, 0);
}
},
RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_);
}
TEST_P(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) {
task_queue_.SendTask([this] {
for (int i = 0; i < kFramerate * 5; ++i) {
qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportQp(kHighQp, 0);
}
});
task_queue_.SendTask(
[this] {
for (int i = 0; i < kFramerate * 5; ++i) {
qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportQp(kHighQp, 0);
}
},
RTC_FROM_HERE);
EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_);
@ -165,84 +173,98 @@ TEST_P(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) {
TEST_P(QualityScalerTest, DownscalesAfterTwoThirdsIfFieldTrialEnabled) {
const bool kDownScaleExpected = !GetParam().empty();
task_queue_.SendTask([this] {
for (int i = 0; i < kFramerate * 5; ++i) {
qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportDroppedFrameByEncoder();
qs_->ReportQp(kHighQp, 0);
}
});
task_queue_.SendTask(
[this] {
for (int i = 0; i < kFramerate * 5; ++i) {
qs_->ReportDroppedFrameByMediaOpt();
qs_->ReportDroppedFrameByEncoder();
qs_->ReportQp(kHighQp, 0);
}
},
RTC_FROM_HERE);
EXPECT_EQ(kDownScaleExpected, observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(kDownScaleExpected ? 1 : 0, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_);
}
TEST_P(QualityScalerTest, KeepsScaleOnNormalQp) {
task_queue_.SendTask([this] { TriggerScale(kKeepScaleAboveLowQp); });
task_queue_.SendTask([this] { TriggerScale(kKeepScaleAboveLowQp); },
RTC_FROM_HERE);
EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_);
}
TEST_P(QualityScalerTest, UpscalesAfterLowQp) {
task_queue_.SendTask([this] { TriggerScale(kScaleUp); });
task_queue_.SendTask([this] { TriggerScale(kScaleUp); }, RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(1, observer_->adapt_up_events_);
}
TEST_P(QualityScalerTest, ScalesDownAndBackUp) {
task_queue_.SendTask([this] { TriggerScale(kScaleDown); });
task_queue_.SendTask([this] { TriggerScale(kScaleDown); }, RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_);
task_queue_.SendTask([this] { TriggerScale(kScaleUp); });
task_queue_.SendTask([this] { TriggerScale(kScaleUp); }, RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(1, observer_->adapt_up_events_);
}
TEST_P(QualityScalerTest, DoesNotScaleUntilEnoughFramesObserved) {
task_queue_.SendTask([this] {
// Not enough frames to make a decision.
for (int i = 0; i < kMinFramesNeededToScale - 1; ++i) {
qs_->ReportQp(kLowQp, 0);
}
});
task_queue_.SendTask(
[this] {
// Not enough frames to make a decision.
for (int i = 0; i < kMinFramesNeededToScale - 1; ++i) {
qs_->ReportQp(kLowQp, 0);
}
},
RTC_FROM_HERE);
EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs));
task_queue_.SendTask([this] {
// Send 1 more. Enough frames observed, should result in an adapt request.
qs_->ReportQp(kLowQp, 0);
});
task_queue_.SendTask(
[this] {
// Send 1 more. Enough frames observed, should result in an adapt
// request.
qs_->ReportQp(kLowQp, 0);
},
RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(1, observer_->adapt_up_events_);
// Samples should be cleared after an adapt request.
task_queue_.SendTask([this] {
// Not enough frames to make a decision.
qs_->ReportQp(kLowQp, 0);
});
task_queue_.SendTask(
[this] {
// Not enough frames to make a decision.
qs_->ReportQp(kLowQp, 0);
},
RTC_FROM_HERE);
EXPECT_FALSE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(0, observer_->adapt_down_events_);
EXPECT_EQ(1, observer_->adapt_up_events_);
}
TEST_P(QualityScalerTest, ScalesDownAndBackUpWithMinFramesNeeded) {
task_queue_.SendTask([this] {
for (int i = 0; i < kMinFramesNeededToScale; ++i) {
qs_->ReportQp(kHighQp + 1, 0);
}
});
task_queue_.SendTask(
[this] {
for (int i = 0; i < kMinFramesNeededToScale; ++i) {
qs_->ReportQp(kHighQp + 1, 0);
}
},
RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(0, observer_->adapt_up_events_);
// Samples cleared.
task_queue_.SendTask([this] {
for (int i = 0; i < kMinFramesNeededToScale; ++i) {
qs_->ReportQp(kLowQp, 0);
}
});
task_queue_.SendTask(
[this] {
for (int i = 0; i < kMinFramesNeededToScale; ++i) {
qs_->ReportQp(kLowQp, 0);
}
},
RTC_FROM_HERE);
EXPECT_TRUE(observer_->event.Wait(kDefaultTimeoutMs));
EXPECT_EQ(1, observer_->adapt_down_events_);
EXPECT_EQ(1, observer_->adapt_up_events_);

View file

@ -1077,8 +1077,10 @@ rtc_source_set("task_queue_for_test") {
deps = [
":checks",
":macromagic",
":rtc_base_approved",
":rtc_event",
":rtc_task_queue",
"../api/task_queue",
"../api/task_queue:default_task_queue_factory",
"task_utils:to_queued_task",
"//third_party/abseil-cpp/absl/strings",

View file

@ -84,16 +84,20 @@ TEST(SequenceCheckerTest, DetachFromThreadAndUseOnTaskQueue) {
SequenceChecker sequence_checker;
sequence_checker.Detach();
TaskQueueForTest queue;
queue.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
queue.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); },
RTC_FROM_HERE);
}
TEST(SequenceCheckerTest, DetachFromTaskQueueAndUseOnThread) {
TaskQueueForTest queue;
queue.SendTask([] {
SequenceChecker sequence_checker;
sequence_checker.Detach();
RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
});
queue.SendTask(
[] {
SequenceChecker sequence_checker;
sequence_checker.Detach();
RunOnDifferentThread(
[&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
},
RTC_FROM_HERE);
}
TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadInDebug) {
@ -106,7 +110,8 @@ TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentTaskQueueInDebug) {
SequenceChecker sequence_checker;
TaskQueueForTest queue;
queue.SendTask(
[&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); });
[&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); },
RTC_FROM_HERE);
}
TEST(SequenceCheckerTest, DetachFromTaskQueueInDebug) {
@ -114,13 +119,15 @@ TEST(SequenceCheckerTest, DetachFromTaskQueueInDebug) {
sequence_checker.Detach();
TaskQueueForTest queue1;
queue1.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
queue1.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); },
RTC_FROM_HERE);
// IsCurrent should return false in debug builds after moving to
// another task queue.
TaskQueueForTest queue2;
queue2.SendTask(
[&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); });
[&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); },
RTC_FROM_HERE);
}
class TestAnnotations {
@ -147,7 +154,7 @@ TEST(SequenceCheckerTest, TestAnnotations) {
void TestAnnotationsOnWrongQueue() {
TestAnnotations annotations;
TaskQueueForTest queue;
queue.SendTask([&] { annotations.ModifyTestVar(); });
queue.SendTask([&] { annotations.ModifyTestVar(); }, RTC_FROM_HERE);
}
#if RTC_DCHECK_IS_ON

View file

@ -14,14 +14,27 @@
#include <utility>
#include "absl/strings/string_view.h"
#include "api/task_queue/task_queue_base.h"
#include "rtc_base/checks.h"
#include "rtc_base/event.h"
#include "rtc_base/location.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/task_utils/to_queued_task.h"
#include "rtc_base/thread_annotations.h"
namespace webrtc {
template <typename Closure>
void SendTask(TaskQueueBase* task_queue, Closure&& task, rtc::Location loc) {
RTC_CHECK(!task_queue->IsCurrent())
<< "Called SendTask to a queue from the same queue at " << loc.ToString();
rtc::Event event;
task_queue->PostTask(
ToQueuedTask(std::forward<Closure>(task), [&event] { event.Set(); }));
RTC_CHECK(event.Wait(/*give_up_after_ms=*/120'000, /*warn_after_ms=*/10'000))
<< "Waited too long at " << loc.ToString();
}
class RTC_LOCKABLE TaskQueueForTest : public rtc::TaskQueue {
public:
using rtc::TaskQueue::TaskQueue;
@ -38,7 +51,7 @@ class RTC_LOCKABLE TaskQueueForTest : public rtc::TaskQueue {
// task queue (i.e. the Run() method always returns |false|.).
template <class Closure>
void SendTask(Closure* task) {
RTC_DCHECK(!IsCurrent());
RTC_CHECK(!IsCurrent());
rtc::Event event;
PostTask(ToQueuedTask(
[&task] { RTC_CHECK_EQ(false, static_cast<QueuedTask*>(task)->Run()); },
@ -49,12 +62,8 @@ class RTC_LOCKABLE TaskQueueForTest : public rtc::TaskQueue {
// A convenience, test-only method that blocks the current thread while
// a task executes on the task queue.
template <class Closure>
void SendTask(Closure&& task) {
RTC_DCHECK(!IsCurrent());
rtc::Event event;
PostTask(
ToQueuedTask(std::forward<Closure>(task), [&event] { event.Set(); }));
event.Wait(rtc::Event::kForever);
void SendTask(Closure&& task, rtc::Location loc) {
::webrtc::SendTask(Get(), std::forward<Closure>(task), loc);
}
};

View file

@ -204,7 +204,7 @@ template <class T>
std::unique_ptr<T> NewObjectCreatedOnTaskQueue() {
std::unique_ptr<T> obj;
webrtc::TaskQueueForTest queue("NewObjectCreatedOnTaskQueue");
queue.SendTask([&] { obj = std::make_unique<T>(); });
queue.SendTask([&] { obj = std::make_unique<T>(); }, RTC_FROM_HERE);
return obj;
}
@ -226,11 +226,13 @@ TEST(WeakPtrTest, WeakPtrInitiateAndUseOnDifferentThreads) {
// Create weak ptr on main thread
WeakPtr<Target> weak_ptr = target->factory.GetWeakPtr();
webrtc::TaskQueueForTest queue("queue");
queue.SendTask([&] {
// Dereference and invalide weak_ptr on another thread.
EXPECT_EQ(weak_ptr.get(), target.get());
target.reset();
});
queue.SendTask(
[&] {
// Dereference and invalide weak_ptr on another thread.
EXPECT_EQ(weak_ptr.get(), target.get());
target.reset();
},
RTC_FROM_HERE);
}
} // namespace rtc

View file

@ -631,6 +631,7 @@ rtc_source_set("single_threaded_task_queue") {
"../rtc_base:checks",
"../rtc_base:deprecation",
"../rtc_base:rtc_base_approved",
"../rtc_base:task_queue_for_test",
"../rtc_base/task_utils:to_queued_task",
]
}

View file

@ -138,16 +138,18 @@ EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
void NetworkEmulationManagerImpl::ClearRoute(EmulatedRoute* route) {
RTC_CHECK(route->active) << "Route already cleared";
task_queue_.SendTask([route]() {
// Remove receiver from intermediate nodes.
for (auto* node : route->via_nodes) {
node->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
}
// Remove destination endpoint from source endpoint's router.
route->from->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
task_queue_.SendTask(
[route]() {
// Remove receiver from intermediate nodes.
for (auto* node : route->via_nodes) {
node->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
}
// Remove destination endpoint from source endpoint's router.
route->from->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
route->active = false;
});
route->active = false;
},
RTC_FROM_HERE);
}
TrafficRoute* NetworkEmulationManagerImpl::CreateTrafficRoute(

View file

@ -379,12 +379,14 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) {
RTC_LOG(INFO) << "Test is done, initiating disconnect sequence.";
task_queue_->SendTask([&stats_poller, this]() {
RTC_DCHECK_RUN_ON(task_queue_.get());
stats_polling_task_.Stop();
// Get final end-of-call stats.
stats_poller.PollStatsAndNotifyObservers();
});
task_queue_->SendTask(
[&stats_poller, this]() {
RTC_DCHECK_RUN_ON(task_queue_.get());
stats_polling_task_.Stop();
// Get final end-of-call stats.
stats_poller.PollStatsAndNotifyObservers();
},
RTC_FROM_HERE);
// We need to detach AEC dumping from peers, because dump uses |task_queue_|
// inside.
@ -393,12 +395,14 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) {
// Stop all client started tasks on task queue to prevent their access to any
// call related objects after these objects will be destroyed during call tear
// down.
task_queue_->SendTask([this]() {
rtc::CritScope crit(&lock_);
for (auto& handle : repeating_task_handles_) {
handle.Stop();
}
});
task_queue_->SendTask(
[this]() {
rtc::CritScope crit(&lock_);
for (auto& handle : repeating_task_handles_) {
handle.Stop();
}
},
RTC_FROM_HERE);
// Tear down the call.
signaling_thread->Invoke<void>(
RTC_FROM_HERE,

View file

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

View file

@ -29,7 +29,7 @@ VideoFrameMatcher::VideoFrameMatcher(
task_queue_("VideoAnalyzer") {}
VideoFrameMatcher::~VideoFrameMatcher() {
task_queue_.SendTask([this] { Finalize(); });
task_queue_.SendTask([this] { Finalize(); }, RTC_FROM_HERE);
}
void VideoFrameMatcher::RegisterLayer(int layer_id) {

View file

@ -67,19 +67,6 @@ DEPRECATED_SingleThreadedTaskQueueForTesting::PostDelayed(
return id;
}
void DEPRECATED_SingleThreadedTaskQueueForTesting::SendTask(Task task) {
RTC_DCHECK(!IsCurrent());
rtc::Event done;
if (PostTask([&task, &done]() {
task();
done.Set();
}) == kInvalidTaskId) {
return;
}
// Give up after 30 seconds, warn after 10.
RTC_CHECK(done.Wait(30000, 10000));
}
bool DEPRECATED_SingleThreadedTaskQueueForTesting::CancelTask(TaskId task_id) {
rtc::CritScope lock(&cs_);
for (auto it = tasks_.begin(); it != tasks_.end(); it++) {

View file

@ -13,12 +13,14 @@
#include <functional>
#include <map>
#include <memory>
#include <utility>
#include "api/task_queue/task_queue_base.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/deprecation.h"
#include "rtc_base/event.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/task_utils/to_queued_task.h"
#include "rtc_base/thread_checker.h"
@ -61,7 +63,12 @@ class DEPRECATED_SingleThreadedTaskQueueForTesting : public TaskQueueBase {
// Send one task to the queue. The function does not return until the task
// has finished executing. No support for canceling the task.
void SendTask(Task task);
// TODO(bugs.webrtc.org/10933): Remove this function in favor of free SendTask
// to reduce direct mentioning of the SingleThreadedTaskQueueForTesting class.
template <typename Closure>
void SendTask(Closure&& task) {
::webrtc::SendTask(this, std::forward<Closure>(task), RTC_FROM_HERE);
}
// Given an identifier to the task, attempts to eject it from the queue.
// Returns true if the task was found and cancelled. Failure possible

View file

@ -431,9 +431,11 @@ TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) {
TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) {
TaskQueueForTest queue("OveruseFrameDetectorTestQueue");
queue.SendTask([&] {
overuse_detector_->StartCheckForOveruse(&queue, options_, observer_);
});
queue.SendTask(
[&] {
overuse_detector_->StartCheckForOveruse(&queue, options_, observer_);
},
RTC_FROM_HERE);
rtc::Event event;
// Expect NormalUsage(). When called, stop the |overuse_detector_| and then
@ -910,9 +912,11 @@ TEST_F(OveruseFrameDetectorTest2, UpdatesExistingSamples) {
TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) {
TaskQueueForTest queue("OveruseFrameDetectorTestQueue");
queue.SendTask([&] {
overuse_detector_->StartCheckForOveruse(&queue, options_, observer_);
});
queue.SendTask(
[&] {
overuse_detector_->StartCheckForOveruse(&queue, options_, observer_);
},
RTC_FROM_HERE);
rtc::Event event;
// Expect NormalUsage(). When called, stop the |overuse_detector_| and then

File diff suppressed because it is too large Load diff