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}
This commit is contained in:
parent
bb081a62dc
commit
8909a63aca
@ -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();
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -151,7 +151,7 @@ void SignalThread::OnMainThreadDestroyed() {
|
||||
main_ = nullptr;
|
||||
}
|
||||
|
||||
bool SignalThread::Worker::IsProcessingMessages() {
|
||||
bool SignalThread::Worker::IsProcessingMessagesForTesting() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user