Use function-local static variable for MessageQueueManager singleton.

Rely on C++11 thread-safe initialization on first call to
MessageQueueManager::Instance(), in the same way as for
ThreadManager::Instance().

Bug: None
Change-Id: I26244f90c5d7f94a2454688297f55bf96617e78c
Reviewed-on: https://webrtc-review.googlesource.com/97721
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24625}
diff --git a/rtc_base/messagequeue.cc b/rtc_base/messagequeue.cc
index 6ff73b5..a561af4 100644
--- a/rtc_base/messagequeue.cc
+++ b/rtc_base/messagequeue.cc
@@ -48,18 +48,9 @@
 //------------------------------------------------------------------
 // MessageQueueManager
 
-MessageQueueManager* MessageQueueManager::instance_ = nullptr;
-
 MessageQueueManager* MessageQueueManager::Instance() {
-  // Note: This is not thread safe, but it is first called before threads are
-  // spawned.
-  if (!instance_)
-    instance_ = new MessageQueueManager;
-  return instance_;
-}
-
-bool MessageQueueManager::IsInitialized() {
-  return instance_ != nullptr;
+  static MessageQueueManager* const instance = new MessageQueueManager;
+  return instance;
 }
 
 MessageQueueManager::MessageQueueManager() : processing_(0) {}
@@ -77,18 +68,9 @@
 }
 
 void MessageQueueManager::Remove(MessageQueue* message_queue) {
-  // If there isn't a message queue manager instance, then there isn't a queue
-  // to remove.
-  if (!instance_)
-    return;
   return Instance()->RemoveInternal(message_queue);
 }
 void MessageQueueManager::RemoveInternal(MessageQueue* message_queue) {
-  // If this is the last MessageQueue, destroy the manager as well so that
-  // we don't leak this object at program shutdown. As mentioned above, this is
-  // not thread-safe, but this should only happen at program termination (when
-  // the ThreadManager is destroyed, and threads are no longer active).
-  bool destroy = false;
   {
     CritScope cs(&crit_);
     // Prevent changes while the list of message queues is processed.
@@ -99,19 +81,10 @@
     if (iter != message_queues_.end()) {
       message_queues_.erase(iter);
     }
-    destroy = message_queues_.empty();
-  }
-  if (destroy) {
-    instance_ = nullptr;
-    delete this;
   }
 }
 
 void MessageQueueManager::Clear(MessageHandler* handler) {
-  // If there isn't a message queue manager instance, then there aren't any
-  // queues to remove this handler from.
-  if (!instance_)
-    return;
   return Instance()->ClearInternal(handler);
 }
 void MessageQueueManager::ClearInternal(MessageHandler* handler) {
@@ -125,9 +98,6 @@
 }
 
 void MessageQueueManager::ProcessAllMessageQueuesForTesting() {
-  if (!instance_) {
-    return;
-  }
   return Instance()->ProcessAllMessageQueuesInternal();
 }
 
@@ -225,7 +195,7 @@
   // is going away.
   SignalQueueDestroyed();
   MessageQueueManager::Remove(this);
-  Clear(nullptr);
+  ClearInternal(nullptr, MQID_ANY, nullptr);
 
   if (ss_) {
     ss_->SetMessageQueue(nullptr);
@@ -480,7 +450,12 @@
                          uint32_t id,
                          MessageList* removed) {
   CritScope cs(&crit_);
+  ClearInternal(phandler, id, removed);
+}
 
+void MessageQueue::ClearInternal(MessageHandler* phandler,
+                                 uint32_t id,
+                                 MessageList* removed) {
   // Remove messages with phandler
 
   if (fPeekKeep_ && msgPeek_.Match(phandler, id)) {
diff --git a/rtc_base/messagequeue.h b/rtc_base/messagequeue.h
index d64ea86..e7e4792 100644
--- a/rtc_base/messagequeue.h
+++ b/rtc_base/messagequeue.h
@@ -43,12 +43,6 @@
   static void Remove(MessageQueue* message_queue);
   static void Clear(MessageHandler* handler);
 
-  // For testing purposes, we expose whether or not the MessageQueueManager
-  // instance has been initialized. It has no other use relative to the rest of
-  // the functions of this class, which auto-initialize the underlying
-  // MessageQueueManager instance when necessary.
-  static bool IsInitialized();
-
   // TODO(nisse): Delete alias, as soon as downstream code is updated.
   static void ProcessAllMessageQueues() { ProcessAllMessageQueuesForTesting(); }
 
@@ -68,7 +62,6 @@
   void ClearInternal(MessageHandler* handler);
   void ProcessAllMessageQueuesInternal();
 
-  static MessageQueueManager* instance_;
   // This list contains all live MessageQueues.
   std::vector<MessageQueue*> message_queues_ RTC_GUARDED_BY(crit_);
 
@@ -305,9 +298,15 @@
   // if false was passed as init_queue to the MessageQueue constructor.
   void DoInit();
 
-  // Perform cleanup, subclasses that override Clear must call this from the
-  // destructor.
-  void DoDestroy();
+  // Does not take any lock. Must be called either while holding crit_, or by
+  // the destructor (by definition, the latter has exclusive access).
+  void ClearInternal(MessageHandler* phandler,
+                     uint32_t id,
+                     MessageList* removed) RTC_EXCLUSIVE_LOCKS_REQUIRED(&crit_);
+
+  // Perform cleanup; subclasses must call this from the destructor,
+  // and are not expected to actually hold the lock.
+  void DoDestroy() RTC_EXCLUSIVE_LOCKS_REQUIRED(&crit_);
 
   void WakeUpSocketServer();
 
diff --git a/rtc_base/messagequeue_unittest.cc b/rtc_base/messagequeue_unittest.cc
index b031bde..d8e8b11 100644
--- a/rtc_base/messagequeue_unittest.cc
+++ b/rtc_base/messagequeue_unittest.cc
@@ -134,22 +134,6 @@
   bool rewrap_;
 };
 
-TEST(MessageQueueManager, Clear) {
-  UnwrapMainThreadScope s;
-  if (MessageQueueManager::IsInitialized()) {
-    RTC_LOG(LS_INFO)
-        << "Unable to run MessageQueueManager::Clear test, since the "
-        << "MessageQueueManager was already initialized by some "
-        << "other test in this run.";
-    return;
-  }
-  bool deleted = false;
-  DeletedMessageHandler* handler = new DeletedMessageHandler(&deleted);
-  delete handler;
-  EXPECT_TRUE(deleted);
-  EXPECT_FALSE(MessageQueueManager::IsInitialized());
-}
-
 // Ensure that ProcessAllMessageQueues does its essential function; process
 // all messages (both delayed and non delayed) up until the current time, on
 // all registered message queues.
diff --git a/rtc_base/thread.cc b/rtc_base/thread.cc
index 61aea90..2d5704e 100644
--- a/rtc_base/thread.cc
+++ b/rtc_base/thread.cc
@@ -482,7 +482,7 @@
     ++iter;
   }
 
-  MessageQueue::Clear(phandler, id, removed);
+  ClearInternal(phandler, id, removed);
 }
 
 #if !defined(WEBRTC_MAC)