Reland "Explicitly wrap main thread in test_main.cc."
This is a reland of 711a31aead9007e42dd73c302c8ec40f9e931619
Changes since original landing:
Rename methods only used by tests, mainly via FakeClock,
MessageQueueManager::ProcessAllMessageQueues
--> ProcessAllMessageQueuesForTesting
MessageQueue::IsProcessingMessages
--> IsProcessingMessagesForTesting
Fix the handling of null rtc::Thread::Current() in
ProcessAllMessageQueuesInternal().
Add override Thread::IsProcessingMessagesForTesting() to return false
for the wrapped main thread, unless it's also the current thread. In
tests, the main thread is typically not processing any messages,
but blocked in an Event::Wait().
Original change's description:
> Explicitly wrap main thread in test_main.cc.
>
> Bug: webrtc:9714
> Change-Id: I6ee234f9a0b88b3656a683f2455c3e4b2acf0d54
> Reviewed-on: https://webrtc-review.googlesource.com/97683
> Reviewed-by: Tommi <tommi@webrtc.org>
> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#24560}
Bug: webrtc:9714
Change-Id: I6f022d46aaf1e28f86f09f2d68c1803b69770126
Reviewed-on: https://webrtc-review.googlesource.com/98060
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24596}
diff --git a/modules/audio_device/ios/audio_device_unittest_ios.mm b/modules/audio_device/ios/audio_device_unittest_ios.mm
index 3baa5b5..47b873d 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 @@
[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 @@
[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 ade9208..f63b85c 100644
--- a/rtc_base/fakeclock.cc
+++ b/rtc_base/fakeclock.cc
@@ -28,7 +28,7 @@
}
// 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 @@
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 035ff07..6ff73b5 100644
--- a/rtc_base/messagequeue.cc
+++ b/rtc_base/messagequeue.cc
@@ -124,7 +124,7 @@
}
}
-void MessageQueueManager::ProcessAllMessageQueues() {
+void MessageQueueManager::ProcessAllMessageQueuesForTesting() {
if (!instance_) {
return;
}
@@ -153,7 +153,7 @@
{
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 @@
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 @@
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 fe64c9c..d64ea86 100644
--- a/rtc_base/messagequeue.h
+++ b/rtc_base/messagequeue.h
@@ -49,10 +49,13 @@
// 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 @@
// 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 1018a62..b031bde 100644
--- a/rtc_base/messagequeue_unittest.cc
+++ b/rtc_base/messagequeue_unittest.cc
@@ -182,7 +182,7 @@
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 @@
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 @@
// 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 58f8761..eb79dc8 100644
--- a/rtc_base/signalthread.cc
+++ b/rtc_base/signalthread.cc
@@ -151,7 +151,7 @@
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 be54d9c..021cf4d 100644
--- a/rtc_base/signalthread.h
+++ b/rtc_base/signalthread.h
@@ -105,7 +105,7 @@
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 373fa39..61aea90 100644
--- a/rtc_base/thread.cc
+++ b/rtc_base/thread.cc
@@ -451,6 +451,11 @@
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 0408a0d..5a46610 100644
--- a/rtc_base/thread.h
+++ b/rtc_base/thread.h
@@ -189,6 +189,7 @@
}
// 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 7c6f9a7..7ecc43a 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 054af65..aefd8f9 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -209,7 +209,7 @@
":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 277d420..46a7de6 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 @@
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,