diff --git a/media/BUILD.gn b/media/BUILD.gn index 9d44cf0e0d..1b2e9c8c58 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -491,6 +491,7 @@ if (rtc_include_tests) { "../rtc_base:rtc_base", "../rtc_base:rtc_base_approved", "../rtc_base:rtc_base_tests_utils", + "../rtc_base:rtc_task_queue_for_test", "../test:test_support", "//testing/gtest", ] diff --git a/media/base/fakevideocapturer.cc b/media/base/fakevideocapturer.cc index cd5a0ddef9..80021e571b 100644 --- a/media/base/fakevideocapturer.cc +++ b/media/base/fakevideocapturer.cc @@ -137,15 +137,19 @@ FakeVideoCapturerWithTaskQueue::FakeVideoCapturerWithTaskQueue( FakeVideoCapturerWithTaskQueue::FakeVideoCapturerWithTaskQueue() {} bool FakeVideoCapturerWithTaskQueue::CaptureFrame() { + if (task_queue_.IsCurrent()) + return FakeVideoCapturer::CaptureFrame(); bool ret = false; - RunSynchronouslyOnTaskQueue( + task_queue_.SendTask( [this, &ret]() { ret = FakeVideoCapturer::CaptureFrame(); }); return ret; } bool FakeVideoCapturerWithTaskQueue::CaptureCustomFrame(int width, int height) { + if (task_queue_.IsCurrent()) + return FakeVideoCapturer::CaptureCustomFrame(width, height); bool ret = false; - RunSynchronouslyOnTaskQueue([this, &ret, width, height]() { + task_queue_.SendTask([this, &ret, width, height]() { ret = FakeVideoCapturer::CaptureCustomFrame(width, height); }); return ret; diff --git a/media/base/fakevideocapturer.h b/media/base/fakevideocapturer.h index 07bd12e3f6..4a49f4504a 100644 --- a/media/base/fakevideocapturer.h +++ b/media/base/fakevideocapturer.h @@ -21,8 +21,7 @@ #include "media/base/fakeframesource.h" #include "media/base/videocapturer.h" #include "media/base/videocommon.h" -#include "rtc_base/event.h" -#include "rtc_base/task_queue.h" +#include "rtc_base/task_queue_for_test.h" #include "rtc_base/timeutils.h" namespace cricket { @@ -73,21 +72,7 @@ class FakeVideoCapturerWithTaskQueue : public FakeVideoCapturer { bool CaptureCustomFrame(int width, int height) override; protected: - template - void RunSynchronouslyOnTaskQueue(Closure&& closure) { - if (task_queue_.IsCurrent()) { - closure(); - return; - } - rtc::Event event(false, false); - task_queue_.PostTask([&closure, &event]() { - closure(); - event.Set(); - }); - event.Wait(rtc::Event::kForever); - } - - rtc::TaskQueue task_queue_{"FakeVideoCapturerWithTaskQueue"}; + rtc::test::TaskQueueForTest task_queue_{"FakeVideoCapturerWithTaskQueue"}; }; } // namespace cricket diff --git a/media/engine/fakewebrtcvideocapturemodule.h b/media/engine/fakewebrtcvideocapturemodule.h index bf23a11277..cd6f25bd56 100644 --- a/media/engine/fakewebrtcvideocapturemodule.h +++ b/media/engine/fakewebrtcvideocapturemodule.h @@ -16,6 +16,7 @@ #include "api/video/i420_buffer.h" #include "media/base/testutils.h" #include "media/engine/webrtcvideocapturer.h" +#include "rtc_base/task_queue_for_test.h" class FakeWebRtcVcmFactory; @@ -60,17 +61,18 @@ class FakeWebRtcVideoCaptureModule : public webrtc::VideoCaptureModule { return true; // Rotation compensation is turned on. } void SendFrame(int w, int h) { - if (!running_) return; + if (!running_ || !callback_) + return; - rtc::scoped_refptr buffer = - webrtc::I420Buffer::Create(w, h); - // Initialize memory to satisfy DrMemory tests. See - // https://bugs.chromium.org/p/libyuv/issues/detail?id=377 - buffer->InitializeData(); - if (callback_) { + task_queue_.SendTask([this, w, h]() { + rtc::scoped_refptr buffer = + webrtc::I420Buffer::Create(w, h); + // Initialize memory to satisfy DrMemory tests. See + // https://bugs.chromium.org/p/libyuv/issues/detail?id=377 + buffer->InitializeData(); callback_->OnFrame( webrtc::VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0)); - } + }); } const webrtc::VideoCaptureCapability& cap() const { @@ -78,6 +80,7 @@ class FakeWebRtcVideoCaptureModule : public webrtc::VideoCaptureModule { } private: + rtc::test::TaskQueueForTest task_queue_{"FakeWebRtcVideoCaptureModule"}; FakeWebRtcVcmFactory* factory_; rtc::VideoSinkInterface* callback_; bool running_; diff --git a/modules/audio_mixer/BUILD.gn b/modules/audio_mixer/BUILD.gn index e3443f30a3..ce46e76169 100644 --- a/modules/audio_mixer/BUILD.gn +++ b/modules/audio_mixer/BUILD.gn @@ -88,7 +88,7 @@ if (rtc_include_tests) { "../../audio/utility:audio_frame_operations", "../../rtc_base:checks", "../../rtc_base:rtc_base_approved", - "../../rtc_base:rtc_task_queue", + "../../rtc_base:rtc_task_queue_for_test", "../../test:test_support", ] } diff --git a/modules/audio_mixer/audio_mixer_impl_unittest.cc b/modules/audio_mixer/audio_mixer_impl_unittest.cc index 4461e6e038..bda470f654 100644 --- a/modules/audio_mixer/audio_mixer_impl_unittest.cc +++ b/modules/audio_mixer/audio_mixer_impl_unittest.cc @@ -21,8 +21,7 @@ #include "modules/audio_mixer/default_output_rate_calculator.h" #include "rtc_base/bind.h" #include "rtc_base/checks.h" -#include "rtc_base/event.h" -#include "rtc_base/task_queue.h" +#include "rtc_base/task_queue_for_test.h" #include "test/gmock.h" using testing::_; @@ -372,14 +371,9 @@ TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) { // This test checks that the initialization and participant addition // can be done on a different thread. TEST(AudioMixer, ConstructFromOtherThread) { - rtc::TaskQueue init_queue("init"); + rtc::test::TaskQueueForTest init_queue("init"); rtc::scoped_refptr mixer; - rtc::Event event(false, false); - init_queue.PostTask([&mixer, &event]() { - mixer = AudioMixerImpl::Create(); - event.Set(); - }); - event.Wait(rtc::Event::kForever); + init_queue.SendTask([&mixer]() { mixer = AudioMixerImpl::Create(); }); MockMixerAudioSource participant; EXPECT_CALL(participant, PreferredSampleRate()) @@ -387,12 +381,9 @@ TEST(AudioMixer, ConstructFromOtherThread) { ResetFrame(participant.fake_frame()); - rtc::TaskQueue participant_queue("participant"); - participant_queue.PostTask([&mixer, &event, &participant]() { - mixer->AddSource(&participant); - event.Set(); - }); - event.Wait(rtc::Event::kForever); + rtc::test::TaskQueueForTest participant_queue("participant"); + participant_queue.SendTask( + [&mixer, &participant]() { mixer->AddSource(&participant); }); EXPECT_CALL(participant, GetAudioFrameWithInfo(kDefaultSampleRateHz, _)) .Times(Exactly(1)); diff --git a/pc/test/fakeperiodicvideocapturer.h b/pc/test/fakeperiodicvideocapturer.h index 37eef2d8b9..e236164a56 100644 --- a/pc/test/fakeperiodicvideocapturer.h +++ b/pc/test/fakeperiodicvideocapturer.h @@ -52,7 +52,7 @@ class FakePeriodicVideoCapturer // So, in order to allow tests to stop frame delivery directly from the // test thread, we expose this method publicly. void StopFrameDelivery() { - RunSynchronouslyOnTaskQueue([this]() { + task_queue_.SendTask([this]() { RTC_DCHECK_RUN_ON(&task_queue_); deliver_frames_ = false; }); diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index d3ec1ebde4..6dccc484be 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -996,6 +996,21 @@ if (rtc_include_tests) { ] } + rtc_source_set("rtc_task_queue_for_test") { + visibility = [ "*" ] + testonly = true + + sources = [ + "task_queue_for_test.cc", + "task_queue_for_test.h", + ] + deps = [ + ":checks", + ":rtc_base_approved", + ":rtc_task_queue", + ] + } + rtc_source_set("rtc_task_queue_unittests") { visibility = [ "*" ] testonly = true @@ -1008,6 +1023,7 @@ if (rtc_include_tests) { ":rtc_base_tests_main", ":rtc_base_tests_utils", ":rtc_task_queue", + ":rtc_task_queue_for_test", "../test:test_support", ] } diff --git a/rtc_base/task_queue_for_test.cc b/rtc_base/task_queue_for_test.cc new file mode 100644 index 0000000000..5d99df5959 --- /dev/null +++ b/rtc_base/task_queue_for_test.cc @@ -0,0 +1,19 @@ +/* + * Copyright 2018 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rtc_base/task_queue_for_test.h" + +namespace rtc { +namespace test { +TaskQueueForTest::TaskQueueForTest(const char* queue_name, Priority priority) + : TaskQueue(queue_name, priority) {} +TaskQueueForTest::~TaskQueueForTest() {} +} // namespace test +} // namespace rtc diff --git a/rtc_base/task_queue_for_test.h b/rtc_base/task_queue_for_test.h new file mode 100644 index 0000000000..70c58fb516 --- /dev/null +++ b/rtc_base/task_queue_for_test.h @@ -0,0 +1,61 @@ +/* + * Copyright 2018 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_BASE_TASK_QUEUE_FOR_TEST_H_ +#define RTC_BASE_TASK_QUEUE_FOR_TEST_H_ + +#include + +#include "rtc_base/checks.h" +#include "rtc_base/event.h" +#include "rtc_base/task_queue.h" + +namespace rtc { +namespace test { +class RTC_LOCKABLE TaskQueueForTest : public TaskQueue { + public: + explicit TaskQueueForTest(const char* queue_name, + Priority priority = Priority::NORMAL); + ~TaskQueueForTest(); + + // A convenience, test-only method that blocks the current thread while + // a task executes on the task queue. + // This variant is specifically for posting custom QueuedTask derived + // implementations that tests do not want to pass ownership of over to the + // task queue (i.e. the Run() method always returns |false|.). + template + void SendTask(Closure* task) { + RTC_DCHECK(!IsCurrent()); + rtc::Event event(false, false); + PostTask(rtc::NewClosure( + [&task]() { + RTC_CHECK_EQ(false, static_cast(task)->Run()); + }, + [&event]() { event.Set(); })); + event.Wait(rtc::Event::kForever); + } + + // A convenience, test-only method that blocks the current thread while + // a task executes on the task queue. + template + void SendTask(Closure&& task) { + RTC_DCHECK(!IsCurrent()); + rtc::Event event(false, false); + PostTask(rtc::NewClosure(std::move(task), [&event]() { event.Set(); })); + event.Wait(rtc::Event::kForever); + } + + private: + RTC_DISALLOW_COPY_AND_ASSIGN(TaskQueueForTest); +}; +} // namespace test +} // namespace rtc + +#endif // RTC_BASE_TASK_QUEUE_FOR_TEST_H_ diff --git a/rtc_base/task_queue_unittest.cc b/rtc_base/task_queue_unittest.cc index d70a5fb090..51956d2f6f 100644 --- a/rtc_base/task_queue_unittest.cc +++ b/rtc_base/task_queue_unittest.cc @@ -21,10 +21,13 @@ #include "rtc_base/bind.h" #include "rtc_base/event.h" #include "rtc_base/gunit.h" -#include "rtc_base/task_queue.h" +#include "rtc_base/task_queue_for_test.h" #include "rtc_base/timeutils.h" +using rtc::test::TaskQueueForTest; + namespace rtc { + namespace { // Noop on all platforms except Windows, where it turns on high precision // multimedia timers which increases the precision of TimeMillis() while in @@ -44,9 +47,7 @@ class EnableHighResTimers { const bool enabled_; #endif }; -} -namespace { void CheckCurrent(Event* signal, TaskQueue* queue) { EXPECT_TRUE(queue->IsCurrent()); if (signal) @@ -76,34 +77,31 @@ TEST(TaskQueueTest, PostAndCheckCurrent) { TEST(TaskQueueTest, PostCustomTask) { static const char kQueueName[] = "PostCustomImplementation"; - Event event(false, false); - TaskQueue queue(kQueueName); + TaskQueueForTest queue(kQueueName); class CustomTask : public QueuedTask { public: - explicit CustomTask(Event* event) : event_(event) {} + CustomTask() {} + bool ran() const { return ran_; } private: bool Run() override { - event_->Set(); - return false; // Never allows the task to be deleted by the queue. + ran_ = true; + return false; // Never allow the task to be deleted by the queue. } - Event* const event_; - } my_task(&event); + bool ran_ = false; + } my_task; - // Please don't do this in production code! :) - queue.PostTask(std::unique_ptr(&my_task)); - EXPECT_TRUE(event.Wait(1000)); + queue.SendTask(&my_task); + EXPECT_TRUE(my_task.ran()); } TEST(TaskQueueTest, PostLambda) { - static const char kQueueName[] = "PostLambda"; - Event event(false, false); - TaskQueue queue(kQueueName); - - queue.PostTask([&event]() { event.Set(); }); - EXPECT_TRUE(event.Wait(1000)); + TaskQueueForTest queue("PostLambda"); + bool ran = false; + queue.SendTask([&ran]() { ran = true; }); + EXPECT_TRUE(ran); } TEST(TaskQueueTest, PostDelayedZero) {