Bug 1445546 - Initialize COM on the MediaManager thread. r?padenot draft
authorMatthew Gregan <kinetik@flim.org>
Tue, 20 Mar 2018 10:31:40 +1300
changeset 769623 70a964f5c4b049e37c9e5e0c3575bd82ce5e7f6e
parent 769622 7862033a42ab4689c373b64bd363db081ffaee0d
push id103191
push usermgregan@mozilla.com
push dateMon, 19 Mar 2018 21:36:50 +0000
reviewerspadenot
bugs1445546
milestone61.0a1
Bug 1445546 - Initialize COM on the MediaManager thread. r?padenot MozReview-Commit-ID: 92FErxjmDE5
dom/media/MediaManager.cpp
dom/media/webrtc/MediaEngineWebRTC.h
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -75,16 +75,17 @@
 #include "MediaEngineDefault.h"
 #if defined(MOZ_WEBRTC)
 #include "MediaEngineWebRTC.h"
 #include "browser_logging/WebRtcLog.h"
 #endif
 
 #if defined (XP_WIN)
 #include "mozilla/WindowsVersion.h"
+#include <objbase.h>
 #include <winsock2.h>
 #include <iphlpapi.h>
 #include <tchar.h>
 #endif
 
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount() and conflicts with MediaStream::GetCurrentTime.
 #ifdef GetCurrentTime
@@ -1991,33 +1992,62 @@ NS_IMPL_ISUPPORTS(MediaManager, nsIMedia
 MediaManager::IsInMediaThread()
 {
   return sSingleton?
       (sSingleton->mMediaThread->thread_id() == PlatformThread::CurrentId()) :
       false;
 }
 #endif
 
+#ifdef XP_WIN
+class MTAThread : public base::Thread {
+public:
+  explicit MTAThread(const char* aName)
+    : base::Thread(aName)
+    , mResult(E_FAIL)
+  {
+  }
+
+protected:
+  virtual void Init() override {
+    mResult = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
+  }
+
+  virtual void CleanUp() override {
+    if (SUCCEEDED(mResult)) {
+      CoUninitialize();
+    }
+  }
+
+private:
+  HRESULT mResult;
+};
+#endif
+
 // NOTE: never Dispatch(....,NS_DISPATCH_SYNC) to the MediaManager
 // thread from the MainThread, as we NS_DISPATCH_SYNC to MainThread
 // from MediaManager thread.
 
 // Guaranteed never to return nullptr.
 /* static */  MediaManager*
 MediaManager::Get() {
   if (!sSingleton) {
     MOZ_ASSERT(NS_IsMainThread());
 
     static int timesCreated = 0;
     timesCreated++;
     MOZ_RELEASE_ASSERT(timesCreated == 1);
 
     sSingleton = new MediaManager();
 
+#ifdef XP_WIN
+    sSingleton->mMediaThread = new MTAThread("MediaManager");
+#else
     sSingleton->mMediaThread = new base::Thread("MediaManager");
+#endif
     base::Thread::Options options;
 #if defined(_WIN32)
     options.message_loop_type = MessageLoop::TYPE_MOZILLA_NONMAINUITHREAD;
 #else
     options.message_loop_type = MessageLoop::TYPE_MOZILLA_NONMAINTHREAD;
 #endif
     if (!sSingleton->mMediaThread->StartWithOptions(options)) {
       MOZ_CRASH();
--- a/dom/media/webrtc/MediaEngineWebRTC.h
+++ b/dom/media/webrtc/MediaEngineWebRTC.h
@@ -156,17 +156,19 @@ public:
       mDeviceIndexes = new nsTArray<int>;
       mDeviceNames = new nsTArray<nsCString>;
       mDefaultDevice = -1;
     }
   }
 
   static void CleanupGlobalData()
   {
-    cubeb_device_collection_destroy(CubebUtils::GetCubebContext(), &mDevices);
+    if (mDevices.device) {
+      cubeb_device_collection_destroy(CubebUtils::GetCubebContext(), &mDevices);
+    }
     delete mDeviceIndexes;
     mDeviceIndexes = nullptr;
     delete mDeviceNames;
     mDeviceNames = nullptr;
   }
 
   int GetNumOfRecordingDevices(int& aDevices)
   {