diff --git a/modules/audio_device/ios/audio_device_unittest_ios.mm b/modules/audio_device/ios/audio_device_unittest_ios.mm index 3baa5b5d4b..47b873d4a9 100644 --- a/modules/audio_device/ios/audio_device_unittest_ios.mm +++ b/modules/audio_device/ios/audio_device_unittest_ios.mm @@ -858,7 +858,7 @@ TEST_F(AudioDeviceTest, testInterruptedAudioSession) { [session notifyDidBeginInterruption]; // Wait for notification to propagate. - rtc::MessageQueueManager::ProcessAllMessageQueues(); + rtc::MessageQueueManager::ProcessAllMessageQueuesForTesting(); EXPECT_TRUE(audio_device->is_interrupted_); // Force it for testing. @@ -869,7 +869,7 @@ TEST_F(AudioDeviceTest, testInterruptedAudioSession) { [session notifyDidEndInterruptionWithShouldResumeSession:YES]; // Wait for notification to propagate. - rtc::MessageQueueManager::ProcessAllMessageQueues(); + rtc::MessageQueueManager::ProcessAllMessageQueuesForTesting(); EXPECT_TRUE(audio_device->is_interrupted_); audio_device->Init(); diff --git a/rtc_base/fakeclock.cc b/rtc_base/fakeclock.cc index ade920893f..f63b85c480 100644 --- a/rtc_base/fakeclock.cc +++ b/rtc_base/fakeclock.cc @@ -28,7 +28,7 @@ void FakeClock::SetTimeNanos(int64_t nanos) { } // If message queues are waiting in a socket select() with a timeout provided // by the OS, they should wake up and dispatch all messages that are ready. - MessageQueueManager::ProcessAllMessageQueues(); + MessageQueueManager::ProcessAllMessageQueuesForTesting(); } void FakeClock::AdvanceTime(webrtc::TimeDelta delta) { @@ -36,7 +36,7 @@ void FakeClock::AdvanceTime(webrtc::TimeDelta delta) { CritScope cs(&lock_); time_ += delta.ns(); } - MessageQueueManager::ProcessAllMessageQueues(); + MessageQueueManager::ProcessAllMessageQueuesForTesting(); } ScopedFakeClock::ScopedFakeClock() { diff --git a/rtc_base/messagequeue.cc b/rtc_base/messagequeue.cc index 035ff07066..6ff73b5d65 100644 --- a/rtc_base/messagequeue.cc +++ b/rtc_base/messagequeue.cc @@ -124,7 +124,7 @@ void MessageQueueManager::ClearInternal(MessageHandler* handler) { } } -void MessageQueueManager::ProcessAllMessageQueues() { +void MessageQueueManager::ProcessAllMessageQueuesForTesting() { if (!instance_) { return; } @@ -153,7 +153,7 @@ void MessageQueueManager::ProcessAllMessageQueuesInternal() { { MarkProcessingCritScope cs(&crit_, &processing_); for (MessageQueue* queue : message_queues_) { - if (!queue->IsProcessingMessages()) { + if (!queue->IsProcessingMessagesForTesting()) { // If the queue is not processing messages, it can // be ignored. If we tried to post a message to it, it would be dropped // or ignored. @@ -163,11 +163,15 @@ void MessageQueueManager::ProcessAllMessageQueuesInternal() { new ScopedIncrement(&queues_not_done)); } } - // Note: One of the message queues may have been on this thread, which is why - // we can't synchronously wait for queues_not_done to go to 0; we need to - // process messages as well. + + rtc::Thread* current = rtc::Thread::Current(); + // Note: One of the message queues may have been on this thread, which is + // why we can't synchronously wait for queues_not_done to go to 0; we need + // to process messages as well. while (AtomicOps::AcquireLoad(&queues_not_done) > 0) { - rtc::Thread::Current()->ProcessMessages(0); + if (current) { + current->ProcessMessages(0); + } } } @@ -245,7 +249,7 @@ bool MessageQueue::IsQuitting() { return AtomicOps::AcquireLoad(&stop_) != 0; } -bool MessageQueue::IsProcessingMessages() { +bool MessageQueue::IsProcessingMessagesForTesting() { return !IsQuitting(); } diff --git a/rtc_base/messagequeue.h b/rtc_base/messagequeue.h index fe64c9c432..d64ea86cbe 100644 --- a/rtc_base/messagequeue.h +++ b/rtc_base/messagequeue.h @@ -49,10 +49,13 @@ class MessageQueueManager { // MessageQueueManager instance when necessary. static bool IsInitialized(); - // Mainly for testing purposes, for use with a simulated clock. + // TODO(nisse): Delete alias, as soon as downstream code is updated. + static void ProcessAllMessageQueues() { ProcessAllMessageQueuesForTesting(); } + + // For testing purposes, for use with a simulated clock. // Ensures that all message queues have processed delayed messages // up until the current point in time. - static void ProcessAllMessageQueues(); + static void ProcessAllMessageQueuesForTesting(); private: static MessageQueueManager* Instance(); @@ -226,7 +229,7 @@ class MessageQueue { // Not all message queues actually process messages (such as SignalThread). // In those cases, it's important to know, before posting, that it won't be // Processed. Normally, this would be true until IsQuitting() is true. - virtual bool IsProcessingMessages(); + virtual bool IsProcessingMessagesForTesting(); // Get() will process I/O until: // 1) A message is available (returns true) diff --git a/rtc_base/messagequeue_unittest.cc b/rtc_base/messagequeue_unittest.cc index 1018a62f9f..b031bdebd1 100644 --- a/rtc_base/messagequeue_unittest.cc +++ b/rtc_base/messagequeue_unittest.cc @@ -182,7 +182,7 @@ TEST(MessageQueueManager, ProcessAllMessageQueues) { b->PostDelayed(RTC_FROM_HERE, 0, &incrementer); rtc::Thread::Current()->Post(RTC_FROM_HERE, &event_signaler); - MessageQueueManager::ProcessAllMessageQueues(); + MessageQueueManager::ProcessAllMessageQueuesForTesting(); EXPECT_EQ(4, AtomicOps::AcquireLoad(&messages_processed)); } @@ -191,7 +191,7 @@ TEST(MessageQueueManager, ProcessAllMessageQueuesWithQuittingThread) { auto t = Thread::CreateWithSocketServer(); t->Start(); t->Quit(); - MessageQueueManager::ProcessAllMessageQueues(); + MessageQueueManager::ProcessAllMessageQueuesForTesting(); } // Test that ProcessAllMessageQueues doesn't hang if a queue clears its @@ -218,7 +218,7 @@ TEST(MessageQueueManager, ProcessAllMessageQueuesWithClearedQueue) { // Post messages (both delayed and non delayed) to both threads. t->Post(RTC_FROM_HERE, &clearer); rtc::Thread::Current()->Post(RTC_FROM_HERE, &event_signaler); - MessageQueueManager::ProcessAllMessageQueues(); + MessageQueueManager::ProcessAllMessageQueuesForTesting(); } class RefCountedHandler : public MessageHandler, public rtc::RefCountInterface { diff --git a/rtc_base/signalthread.cc b/rtc_base/signalthread.cc index 58f8761b80..eb79dc84fe 100644 --- a/rtc_base/signalthread.cc +++ b/rtc_base/signalthread.cc @@ -151,7 +151,7 @@ void SignalThread::OnMainThreadDestroyed() { main_ = nullptr; } -bool SignalThread::Worker::IsProcessingMessages() { +bool SignalThread::Worker::IsProcessingMessagesForTesting() { return false; } diff --git a/rtc_base/signalthread.h b/rtc_base/signalthread.h index be54d9cb4a..021cf4d78d 100644 --- a/rtc_base/signalthread.h +++ b/rtc_base/signalthread.h @@ -105,7 +105,7 @@ class SignalThread : public sigslot::has_slots<>, protected MessageHandler { explicit Worker(SignalThread* parent); ~Worker() override; void Run() override; - bool IsProcessingMessages() override; + bool IsProcessingMessagesForTesting() override; private: SignalThread* parent_; diff --git a/rtc_base/thread.cc b/rtc_base/thread.cc index 373fa3952d..61aea9086a 100644 --- a/rtc_base/thread.cc +++ b/rtc_base/thread.cc @@ -451,6 +451,11 @@ void Thread::InvokeInternal(const Location& posted_from, Send(posted_from, handler); } +bool Thread::IsProcessingMessagesForTesting() { + return (owned_ || IsCurrent()) && + MessageQueue::IsProcessingMessagesForTesting(); +} + void Thread::Clear(MessageHandler* phandler, uint32_t id, MessageList* removed) { diff --git a/rtc_base/thread.h b/rtc_base/thread.h index 0408a0d4d0..5a466104aa 100644 --- a/rtc_base/thread.h +++ b/rtc_base/thread.h @@ -189,6 +189,7 @@ class RTC_LOCKABLE Thread : public MessageQueue { } // From MessageQueue + bool IsProcessingMessagesForTesting() override; void Clear(MessageHandler* phandler, uint32_t id = MQID_ANY, MessageList* removed = nullptr) override; diff --git a/sdk/objc/unittests/RTCAudioDevice_xctest.mm b/sdk/objc/unittests/RTCAudioDevice_xctest.mm index 7c6f9a7901..7ecc43a77a 100644 --- a/sdk/objc/unittests/RTCAudioDevice_xctest.mm +++ b/sdk/objc/unittests/RTCAudioDevice_xctest.mm @@ -93,7 +93,7 @@ [self.audioSession notifyDidBeginInterruption]; // Wait for notification to propagate. - rtc::MessageQueueManager::ProcessAllMessageQueues(); + rtc::MessageQueueManager::ProcessAllMessageQueuesForTesting(); XCTAssertTrue(_audio_device->IsInterrupted()); // Force it for testing. @@ -101,7 +101,7 @@ [self.audioSession notifyDidEndInterruptionWithShouldResumeSession:YES]; // Wait for notification to propagate. - rtc::MessageQueueManager::ProcessAllMessageQueues(); + rtc::MessageQueueManager::ProcessAllMessageQueuesForTesting(); XCTAssertTrue(_audio_device->IsInterrupted()); _audio_device->Init(); diff --git a/test/BUILD.gn b/test/BUILD.gn index 054af655d6..aefd8f9509 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -209,7 +209,7 @@ if (rtc_include_tests) { ":field_trial", ":fileutils", ":perf_test", - "../rtc_base:rtc_base_approved", + "../rtc_base:rtc_base", "../system_wrappers:field_trial_default", "../system_wrappers:metrics_default", "../system_wrappers:runtime_enabled_features_default", diff --git a/test/test_main.cc b/test/test_main.cc index 277d420c67..46a7de6b22 100644 --- a/test/test_main.cc +++ b/test/test_main.cc @@ -10,6 +10,7 @@ #include "rtc_base/flags.h" #include "rtc_base/logging.h" +#include "rtc_base/thread.h" #include "system_wrappers/include/field_trial_default.h" #include "system_wrappers/include/metrics_default.h" #include "test/field_trial.h" @@ -87,6 +88,15 @@ int main(int argc, char* argv[]) { rtc::LogMessage::SetLogToStderr(FLAG_logs); + // Ensure that main thread gets wrapped as an rtc::Thread. + // TODO(bugs.webrt.org/9714): It might be better to avoid wrapping the main + // thread, or leave it to individual tests that need it. But as long as we + // have automatic thread wrapping, we need this to avoid that some other + // random thread (which one depending on which tests are run) gets + // automatically wrapped. + rtc::ThreadManager::Instance()->WrapCurrentThread(); + RTC_CHECK(rtc::Thread::Current()); + #if defined(WEBRTC_IOS) rtc::test::InitTestSuite(RUN_ALL_TESTS, argc, argv,