Bug 1267918 - Ensure GMPCrashHelper instances are destroyed on the main thread. r=karlt
authorChris Pearce <cpearce@mozilla.com>
Thu, 30 Jun 2016 14:19:08 +1200
changeset 383176 94feba0c91327fb20850c5e7224d81b0ac72af2b
parent 383175 5bdad12ea4de6852849f32dec2c4e934e911067c
child 383177 d46af3143920e130e065b924b73fe301d44328a0
push id21963
push userdmitchell@mozilla.com
push dateFri, 01 Jul 2016 19:54:18 +0000
reviewerskarlt
bugs1267918
milestone50.0a1
Bug 1267918 - Ensure GMPCrashHelper instances are destroyed on the main thread. r=karlt MozReview-Commit-ID: 7GFx6uoyAi9
dom/media/gmp/GMPService.cpp
dom/media/gmp/GMPService.h
--- a/dom/media/gmp/GMPService.cpp
+++ b/dom/media/gmp/GMPService.cpp
@@ -29,19 +29,21 @@
 #include "mozilla/SandboxInfo.h"
 #endif
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsHashKeys.h"
 #include "nsIFile.h"
 #include "nsISimpleEnumerator.h"
+#include "nsThreadUtils.h"
 
 #include "mozilla/dom/PluginCrashedEvent.h"
 #include "mozilla/EventDispatcher.h"
+#include "mozilla/Attributes.h"
 
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 LogModule*
@@ -652,8 +654,22 @@ void GeckoMediaPluginService::Disconnect
     if (helpers->IsEmpty()) {
       iter.Remove();
     }
   }
 }
 
 } // namespace gmp
 } // namespace mozilla
+
+NS_IMPL_ADDREF(GMPCrashHelper)
+NS_IMPL_RELEASE_WITH_DESTROY(GMPCrashHelper, Destroy())
+
+void
+GMPCrashHelper::Destroy()
+{
+  if (NS_IsMainThread()) {
+    delete this;
+  } else {
+    // Don't addref, as then we'd end up releasing after the detele runs!
+    NS_DispatchToMainThread(mozilla::NewNonOwningRunnableMethod(this, &GMPCrashHelper::Destroy));
+  }
+}
--- a/dom/media/gmp/GMPService.h
+++ b/dom/media/gmp/GMPService.h
@@ -16,29 +16,42 @@
 #include "nsCOMPtr.h"
 #include "nsIThread.h"
 #include "nsThreadUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDocument.h"
 #include "nsIWeakReference.h"
 #include "mozilla/AbstractThread.h"
 #include "nsClassHashtable.h"
+#include "nsISupportsImpl.h"
 
 template <class> struct already_AddRefed;
 
 // For every GMP actor requested, the caller can specify a crash helper,
 // which is an object which supplies the nsPIDOMWindowInner to which we'll
 // dispatch the PluginCrashed event if the GMP crashes.
+// GMPCrashHelper has threadsafe refcounting. Its release method ensures
+// that instances are destroyed on the main thread.
 class GMPCrashHelper
 {
 public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPCrashHelper)
+  NS_METHOD_(MozExternalRefCountType) AddRef(void);
+  NS_METHOD_(MozExternalRefCountType) Release(void);
+
+  // Called on the main thread.
   virtual already_AddRefed<nsPIDOMWindowInner> GetPluginCrashedEventTarget() = 0;
+
 protected:
-  virtual ~GMPCrashHelper() {}
+  virtual ~GMPCrashHelper()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+  }
+  void Destroy();
+  mozilla::ThreadSafeAutoRefCnt mRefCnt;
+  NS_DECL_OWNINGTHREAD
 };
 
 namespace mozilla {
 
 extern LogModule* GetGMPLog();
 
 namespace gmp {