Bug 1312030 - Remove MediaParent singleton to work with multi content processes. draft
authorJan-Ivar Bruaroey <jib@mozilla.com>
Tue, 01 Nov 2016 07:44:02 -0400
changeset 432310 38f22b6e3835fc8000fafbea1dd1134a18dcb9f7
parent 431855 37ab1d54a08e7e1431660b22377428b74dcd090a
child 535591 e1440e723eda8863cab3268f661b4841131e4544
push id34249
push userjbruaroey@mozilla.com
push dateTue, 01 Nov 2016 16:01:46 +0000
bugs1312030
milestone52.0a1
Bug 1312030 - Remove MediaParent singleton to work with multi content processes. MozReview-Commit-ID: 8JONCRge6SU
dom/media/MediaManager.cpp
dom/media/MediaManager.h
dom/media/systemservices/MediaChild.cpp
dom/media/systemservices/MediaParent.cpp
dom/media/systemservices/MediaParent.h
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1914,19 +1914,19 @@ MediaManager::GetInstance()
   RefPtr<MediaManager> service = MediaManager::Get();
   return service.forget();
 }
 
 media::Parent<media::NonE10s>*
 MediaManager::GetNonE10sParent()
 {
   if (!mNonE10sParent) {
-    mNonE10sParent = MakeUnique<media::Parent<media::NonE10s>>(true);
+    mNonE10sParent = new media::Parent<media::NonE10s>();
   }
-  return mNonE10sParent.get();
+  return mNonE10sParent;
 }
 
 /* static */ void
 MediaManager::StartupInit()
 {
 #ifdef WIN32
   if (IsVistaOrLater() && !IsWin8OrLater()) {
     // Bug 1107702 - Older Windows fail in GetAdaptersInfo (and others) if the
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -328,14 +328,14 @@ private:
 
   static StaticRefPtr<MediaManager> sSingleton;
 
   media::CoatCheck<PledgeSourceSet> mOutstandingPledges;
   media::CoatCheck<PledgeChar> mOutstandingCharPledges;
   media::CoatCheck<PledgeVoid> mOutstandingVoidPledges;
 public:
   media::CoatCheck<media::Pledge<nsCString>> mGetOriginKeyPledges;
-  UniquePtr<media::Parent<media::NonE10s>> mNonE10sParent;
+  RefPtr<media::Parent<media::NonE10s>> mNonE10sParent;
 };
 
 } // namespace mozilla
 
 #endif // MOZILLA_MEDIAMANAGER_H
--- a/dom/media/systemservices/MediaChild.cpp
+++ b/dom/media/systemservices/MediaChild.cpp
@@ -41,17 +41,17 @@ void
 SanitizeOriginKeys(const uint64_t& aSinceWhen, bool aOnlyPrivateBrowsing)
 {
   LOG(("SanitizeOriginKeys since %llu %s", aSinceWhen,
        (aOnlyPrivateBrowsing? "in Private Browsing." : ".")));
 
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     // Avoid opening MediaManager in this case, since this is called by
     // sanitize.js when cookies are cleared, which can happen on startup.
-    auto tmpParent = MakeUnique<Parent<NonE10s>>(true);
+    RefPtr<Parent<NonE10s>> tmpParent = new Parent<NonE10s>();
     tmpParent->RecvSanitizeOriginKeys(aSinceWhen, aOnlyPrivateBrowsing);
   } else {
     Child::Get()->SendSanitizeOriginKeys(aSinceWhen, aOnlyPrivateBrowsing);
   }
 }
 
 static Child* sChild;
 
--- a/dom/media/systemservices/MediaParent.cpp
+++ b/dom/media/systemservices/MediaParent.cpp
@@ -32,18 +32,16 @@ mozilla::LazyLogModule gMediaParentLog("
 // deviceIds to be unique per origin, to avoid them being supercookies.
 
 #define ORIGINKEYS_FILE "enumerate_devices.txt"
 #define ORIGINKEYS_VERSION "1"
 
 namespace mozilla {
 namespace media {
 
-static Parent<PMediaParent>* sIPCServingParent;
-
 static OriginKeyStore* sOriginKeyStore = nullptr;
 
 class OriginKeyStore : public nsISupports
 {
   NS_DECL_THREADSAFE_ISUPPORTS
   class OriginKey
   {
   public:
@@ -350,39 +348,29 @@ public:
 
   // Only accessed on StreamTS thread
   OriginKeysLoader mOriginKeys;
   OriginKeysTable mPrivateBrowsingOriginKeys;
 };
 
 NS_IMPL_ISUPPORTS0(OriginKeyStore)
 
-template<> /* static */
-Parent<PMediaParent>* Parent<PMediaParent>::GetSingleton()
-{
-  return sIPCServingParent;
-}
-
-template<> /* static */
-Parent<NonE10s>* Parent<NonE10s>::GetSingleton()
-{
-  RefPtr<MediaManager> mgr = MediaManager::GetInstance();
+bool NonE10s::SendGetOriginKeyResponse(const uint32_t& aRequestId,
+                                       nsCString aKey) {
+  MediaManager* mgr = MediaManager::GetIfExists();
   if (!mgr) {
-    return nullptr;
+    return false;
   }
-  return mgr->GetNonE10sParent();
+  RefPtr<Pledge<nsCString>> pledge = mgr->mGetOriginKeyPledges.Remove(aRequestId);
+  if (pledge) {
+    pledge->Resolve(aKey);
+  }
+  return true;
 }
 
-// TODO: Remove once upgraded to GCC 4.8+ on linux. Bogus error on static func:
-// error: 'this' was not captured for this lambda function
-
-template<class Super> static
-Parent<Super>* GccGetSingleton() { return Parent<Super>::GetSingleton(); };
-
-
 template<class Super> bool
 Parent<Super>::RecvGetOriginKey(const uint32_t& aRequestId,
                                 const nsCString& aOrigin,
                                 const bool& aPrivateBrowsing,
                                 const bool& aPersist)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -399,73 +387,58 @@ Parent<Super>::RecvGetOriginKey(const ui
   // Then over to stream-transport thread to do the actual file io.
   // Stash a pledge to hold the answer and get an id for this request.
 
   RefPtr<Pledge<nsCString>> p = new Pledge<nsCString>();
   uint32_t id = mOutstandingPledges.Append(*p);
 
   nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
   MOZ_ASSERT(sts);
-  RefPtr<OriginKeyStore> store(mOriginKeyStore);
-  bool sameProcess = mSameProcess;
+  RefPtr<Parent<Super>> that(this);
 
-  rv = sts->Dispatch(NewRunnableFrom([id, profileDir, store, sameProcess, aOrigin,
+  rv = sts->Dispatch(NewRunnableFrom([this, that, id, profileDir, aOrigin,
                                       aPrivateBrowsing, aPersist]() -> nsresult {
     MOZ_ASSERT(!NS_IsMainThread());
-    store->mOriginKeys.SetProfileDir(profileDir);
+    mOriginKeyStore->mOriginKeys.SetProfileDir(profileDir);
     nsCString result;
     if (aPrivateBrowsing) {
-      store->mPrivateBrowsingOriginKeys.GetOriginKey(aOrigin, result);
+      mOriginKeyStore->mPrivateBrowsingOriginKeys.GetOriginKey(aOrigin, result);
     } else {
-      store->mOriginKeys.GetOriginKey(aOrigin, result, aPersist);
+      mOriginKeyStore->mOriginKeys.GetOriginKey(aOrigin, result, aPersist);
     }
 
     // Pass result back to main thread.
     nsresult rv;
-    rv = NS_DispatchToMainThread(NewRunnableFrom([id, store, sameProcess,
+    rv = NS_DispatchToMainThread(NewRunnableFrom([this, that, id,
                                                   result]() -> nsresult {
-      Parent* parent = GccGetSingleton<Super>(); // GetSingleton();
-      if (!parent) {
+      if (mDestroyed) {
         return NS_OK;
       }
-      RefPtr<Pledge<nsCString>> p = parent->mOutstandingPledges.Remove(id);
+      RefPtr<Pledge<nsCString>> p = mOutstandingPledges.Remove(id);
       if (!p) {
         return NS_ERROR_UNEXPECTED;
       }
       p->Resolve(result);
       return NS_OK;
     }), NS_DISPATCH_NORMAL);
 
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     return NS_OK;
   }), NS_DISPATCH_NORMAL);
 
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return false;
   }
-
-  p->Then([aRequestId, sameProcess](const nsCString& aKey) mutable {
-    if (!sameProcess) {
-      if (!sIPCServingParent) {
-        return NS_OK;
-      }
-      Unused << sIPCServingParent->SendGetOriginKeyResponse(aRequestId, aKey);
-    } else {
-      RefPtr<MediaManager> mgr = MediaManager::GetInstance();
-      if (!mgr) {
-        return NS_OK;
-      }
-      RefPtr<Pledge<nsCString>> pledge =
-          mgr->mGetOriginKeyPledges.Remove(aRequestId);
-      if (pledge) {
-        pledge->Resolve(aKey);
-      }
+  p->Then([this, that, aRequestId](const nsCString& aKey) mutable {
+    if (mDestroyed) {
+      return NS_OK;
     }
+    Unused << this->SendGetOriginKeyResponse(aRequestId, aKey);
     return NS_OK;
   });
   return true;
 }
 
 template<class Super> bool
 Parent<Super>::RecvSanitizeOriginKeys(const uint64_t& aSinceWhen,
                                       const bool& aOnlyPrivateBrowsing)
@@ -503,44 +476,41 @@ template<class Super> void
 Parent<Super>::ActorDestroy(ActorDestroyReason aWhy)
 {
   // No more IPC from here
   mDestroyed = true;
   LOG((__FUNCTION__));
 }
 
 template<class Super>
-Parent<Super>::Parent(bool aSameProcess)
+Parent<Super>::Parent()
   : mOriginKeyStore(OriginKeyStore::Get())
   , mDestroyed(false)
-  , mSameProcess(aSameProcess)
 {
   LOG(("media::Parent: %p", this));
 }
 
 template<class Super>
 Parent<Super>::~Parent()
 {
   LOG(("~media::Parent: %p", this));
 }
 
 PMediaParent*
 AllocPMediaParent()
 {
-  MOZ_ASSERT(!sIPCServingParent);
-  sIPCServingParent = new Parent<PMediaParent>();
-  return sIPCServingParent;
+  Parent<PMediaParent>* obj = new Parent<PMediaParent>();
+  obj->AddRef();
+  return obj;
 }
 
 bool
 DeallocPMediaParent(media::PMediaParent *aActor)
 {
-  MOZ_ASSERT(sIPCServingParent == static_cast<Parent<PMediaParent>*>(aActor));
-  delete sIPCServingParent;
-  sIPCServingParent = nullptr;
+  static_cast<Parent<PMediaParent>*>(aActor)->Release();
   return true;
 }
 
 } // namespace media
 } // namespace mozilla
 
 // Instantiate templates to satisfy linker
 template class mozilla::media::Parent<mozilla::media::NonE10s>;
--- a/dom/media/systemservices/MediaParent.h
+++ b/dom/media/systemservices/MediaParent.h
@@ -11,17 +11,17 @@
 
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/media/PMediaParent.h"
 
 namespace mozilla {
 namespace media {
 
 // media::Parent implements the chrome-process side of ipc for media::Child APIs
-// A "SameProcess" version may also be created to service non-e10s calls.
+// A same-process version may also be created to service non-e10s calls.
 
 class OriginKeyStore;
 
 class NonE10s
 {
   typedef mozilla::ipc::IProtocolManager<mozilla::ipc::IProtocol>::ActorDestroyReason
       ActorDestroyReason;
 public:
@@ -30,43 +30,45 @@ protected:
   virtual bool RecvGetOriginKey(const uint32_t& aRequestId,
                                 const nsCString& aOrigin,
                                 const bool& aPrivateBrowsing,
                                 const bool& aPersist) = 0;
   virtual bool RecvSanitizeOriginKeys(const uint64_t& aSinceWhen,
                                       const bool& aOnlyPrivateBrowsing) = 0;
   virtual void
   ActorDestroy(ActorDestroyReason aWhy) = 0;
+
+  bool SendGetOriginKeyResponse(const uint32_t& aRequestId,
+                                nsCString aKey);
 };
 
 // Super = PMediaParent or NonE10s
 
 template<class Super>
 class Parent : public Super
 {
   typedef mozilla::ipc::IProtocolManager<mozilla::ipc::IProtocol>::ActorDestroyReason
       ActorDestroyReason;
 public:
-  static Parent* GetSingleton();
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Parent<Super>)
 
   virtual bool RecvGetOriginKey(const uint32_t& aRequestId,
                                 const nsCString& aOrigin,
                                 const bool& aPrivateBrowsing,
                                 const bool& aPersist) override;
   virtual bool RecvSanitizeOriginKeys(const uint64_t& aSinceWhen,
                                       const bool& aOnlyPrivateBrowsing) override;
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
-  explicit Parent(bool aSameProcess = false);
+  Parent();
+private:
   virtual ~Parent();
-private:
 
   RefPtr<OriginKeyStore> mOriginKeyStore;
   bool mDestroyed;
-  bool mSameProcess;
 
   CoatCheck<Pledge<nsCString>> mOutstandingPledges;
 };
 
 PMediaParent* AllocPMediaParent();
 bool DeallocPMediaParent(PMediaParent *aActor);
 
 } // namespace media