Bug 1267918 - Ensure GMPCrashHelper instances are destroyed on the main thread. r=karlt draft
authorChris Pearce <cpearce@mozilla.com>
Thu, 30 Jun 2016 14:19:08 +1200
changeset 383057 15a5cccb0549ec96b9d752de7e299e5bc621acec
parent 383036 4eee756f6abf7a6212b6a3ce31dcb8182f12999b
child 383058 48b83836660860a484b4844028366657cd1e9d1f
push id21911
push usercpearce@mozilla.com
push dateFri, 01 Jul 2016 04:05:57 +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 {
+    GMPCrashHelper* MOZ_OWNING_REF self = this;
+    NS_DispatchToMainThread(NS_NewRunnableFunction([self] { delete self; }));
+  }
+}
--- 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 {