Bug 959886 - Handle offline cache updates in parent process after windows are being torn down in child processes. r=mayhemer, a=1.3+
authorBen Turner <bent.mozilla@gmail.com>
Wed, 15 Jan 2014 12:20:33 -0800
changeset 174868 a80824cde66013cc55bade162d1ebc67bb780005
parent 174867 6abe246786bec4fd5c75b42902402bc194dafaec
child 174869 8d2d7087d6ad683ac10431bdd8700eebdcdff2d0
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer, 1
bugs959886
milestone28.0a2
Bug 959886 - Handle offline cache updates in parent process after windows are being torn down in child processes. r=mayhemer, a=1.3+
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
uriloader/prefetch/OfflineCacheUpdateChild.h
uriloader/prefetch/OfflineCacheUpdateParent.cpp
uriloader/prefetch/OfflineCacheUpdateParent.h
uriloader/prefetch/POfflineCacheUpdate.ipdl
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -270,16 +270,24 @@ TabParent::Destroy()
   unused << SendDestroy();
 
   const InfallibleTArray<PIndexedDBParent*>& idbParents =
     ManagedPIndexedDBParent();
   for (uint32_t i = 0; i < idbParents.Length(); ++i) {
     static_cast<IndexedDBParent*>(idbParents[i])->Disconnect();
   }
 
+  const InfallibleTArray<POfflineCacheUpdateParent*>& ocuParents =
+    ManagedPOfflineCacheUpdateParent();
+  for (uint32_t i = 0; i < ocuParents.Length(); ++i) {
+    nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> ocuParent =
+      static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(ocuParents[i]);
+    ocuParent->StopSendingMessagesToChild();
+  }
+
   if (RenderFrameParent* frame = GetRenderFrame()) {
     frame->Destroy();
   }
   mIsDestroyed = true;
 
   Manager()->NotifyTabDestroying(this);
   mMarkedDestroying = true;
 }
@@ -1551,42 +1559,52 @@ TabParent::DeallocPRenderFrameParent(PRe
 {
   delete aFrame;
   return true;
 }
 
 mozilla::docshell::POfflineCacheUpdateParent*
 TabParent::AllocPOfflineCacheUpdateParent(const URIParams& aManifestURI,
                                           const URIParams& aDocumentURI,
-                                          const bool& stickDocument)
+                                          const bool& aStickDocument)
 {
   nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
     new mozilla::docshell::OfflineCacheUpdateParent(OwnOrContainingAppId(),
                                                     IsBrowserElement());
-
-  nsresult rv = update->Schedule(aManifestURI, aDocumentURI, stickDocument);
-  if (NS_FAILED(rv)) {
-    // Must dispatch since the parent is not at this moment ready yet.
-    nsRefPtr<nsRunnableMethod<mozilla::docshell::OfflineCacheUpdateParent> > event =
-      NS_NewRunnableMethod(update, &mozilla::docshell::OfflineCacheUpdateParent::Kill);
-    NS_DispatchToCurrentThread(event);
-  }
-
-  POfflineCacheUpdateParent* result = update.get();
-  update.forget();
-  return result;
+  // Use this reference as the IPDL reference.
+  return update.forget().get();
 }
 
 bool
-TabParent::DeallocPOfflineCacheUpdateParent(mozilla::docshell::POfflineCacheUpdateParent* actor)
+TabParent::RecvPOfflineCacheUpdateConstructor(POfflineCacheUpdateParent* aActor,
+                                              const URIParams& aManifestURI,
+                                              const URIParams& aDocumentURI,
+                                              const bool& aStickDocument)
 {
-  mozilla::docshell::OfflineCacheUpdateParent* update =
-    static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(actor);
+  MOZ_ASSERT(aActor);
+
+  nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
+    static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor);
+
+  nsresult rv = update->Schedule(aManifestURI, aDocumentURI, aStickDocument);
+  if (NS_FAILED(rv) && !IsDestroyed()) {
+    // Inform the child of failure.
+    unused << update->SendFinish(false, false);
+  }
 
-  update->Release();
+  return true;
+}
+
+bool
+TabParent::DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActor)
+{
+  // Reclaim the IPDL reference.
+  nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
+    dont_AddRef(
+      static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor));
   return true;
 }
 
 bool
 TabParent::RecvSetOfflinePermission(const IPC::Principal& aPrincipal)
 {
   nsIPrincipal* principal = aPrincipal;
   nsContentUtils::MaybeAllowOfflineAppByDefault(principal, nullptr);
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -224,21 +224,29 @@ public:
                                  const uint32_t& renderFlags, const bool& flushLayout,
                                  const nsIntSize& renderSize);
     virtual bool DeallocPDocumentRendererParent(PDocumentRendererParent* actor);
 
     virtual PContentPermissionRequestParent*
     AllocPContentPermissionRequestParent(const nsCString& aType, const nsCString& aAccess, const IPC::Principal& aPrincipal);
     virtual bool DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor);
 
-    virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdateParent(
-            const URIParams& aManifestURI,
-            const URIParams& aDocumentURI,
-            const bool& stickDocument) MOZ_OVERRIDE;
-    virtual bool DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* actor);
+    virtual POfflineCacheUpdateParent*
+    AllocPOfflineCacheUpdateParent(const URIParams& aManifestURI,
+                                   const URIParams& aDocumentURI,
+                                   const bool& aStickDocument) MOZ_OVERRIDE;
+    virtual bool
+    RecvPOfflineCacheUpdateConstructor(POfflineCacheUpdateParent* aActor,
+                                       const URIParams& aManifestURI,
+                                       const URIParams& aDocumentURI,
+                                       const bool& stickDocument) MOZ_OVERRIDE;
+    virtual bool
+    DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActor)
+                                     MOZ_OVERRIDE;
+
     virtual bool RecvSetOfflinePermission(const IPC::Principal& principal);
 
     bool GetGlobalJSObject(JSContext* cx, JSObject** globalp);
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIAUTHPROMPTPROVIDER
     NS_DECL_NSISECUREBROWSERUI
 
--- a/uriloader/prefetch/OfflineCacheUpdateChild.h
+++ b/uriloader/prefetch/OfflineCacheUpdateChild.h
@@ -26,26 +26,26 @@ class OfflineCacheUpdateChild : public n
                               , public POfflineCacheUpdateChild
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOFFLINECACHEUPDATE
 
     virtual bool
     RecvNotifyStateEvent(const uint32_t& stateEvent,
-                         const uint64_t& byteProgress);
+                         const uint64_t& byteProgress) MOZ_OVERRIDE;
 
     virtual bool
     RecvAssociateDocuments(
             const nsCString& cacheGroupId,
-            const nsCString& cacheClientId);
+            const nsCString& cacheClientId) MOZ_OVERRIDE;
 
     virtual bool
-    RecvFinish(const bool& succeded,
-               const bool& isUpgrade);
+    RecvFinish(const bool& succeeded,
+               const bool& isUpgrade) MOZ_OVERRIDE;
 
     OfflineCacheUpdateChild(nsIDOMWindow* aWindow);
     ~OfflineCacheUpdateChild();
 
     void SetDocument(nsIDOMDocument *aDocument);
 
 private:
     nsresult AssociateDocument(nsIDOMDocument *aDocument,
--- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp
@@ -53,20 +53,17 @@ NS_IMPL_ISUPPORTS2(OfflineCacheUpdatePar
 
 OfflineCacheUpdateParent::OfflineCacheUpdateParent(uint32_t aAppId,
                                                    bool aIsInBrowser)
     : mIPCClosed(false)
     , mIsInBrowserElement(aIsInBrowser)
     , mAppId(aAppId)
 {
     // Make sure the service has been initialized
-    nsOfflineCacheUpdateService* service =
-        nsOfflineCacheUpdateService::EnsureService();
-    if (!service)
-        return;
+    nsOfflineCacheUpdateService::EnsureService();
 
     LOG(("OfflineCacheUpdateParent::OfflineCacheUpdateParent [%p]", this));
 }
 
 OfflineCacheUpdateParent::~OfflineCacheUpdateParent()
 {
     LOG(("OfflineCacheUpdateParent::~OfflineCacheUpdateParent [%p]", this));
 }
@@ -136,22 +133,16 @@ OfflineCacheUpdateParent::Schedule(const
         nsCOMPtr<nsIURI> stickURI;
         documentURI->Clone(getter_AddRefs(stickURI));
         update->StickDocument(stickURI);
     }
 
     return NS_OK;
 }
 
-void
-OfflineCacheUpdateParent::Kill()
-{
-    unused << SendFinish(false, false);
-}
-
 NS_IMETHODIMP
 OfflineCacheUpdateParent::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, uint32_t state)
 {
     if (mIPCClosed)
         return NS_ERROR_UNEXPECTED;
 
     LOG(("OfflineCacheUpdateParent::StateEvent [%p]", this));
 
--- a/uriloader/prefetch/OfflineCacheUpdateParent.h
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.h
@@ -35,25 +35,28 @@ public:
     NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
     NS_DECL_NSILOADCONTEXT
 
     nsresult
     Schedule(const URIParams& manifestURI,
              const URIParams& documentURI,
              const bool& stickDocument);
 
-    void Kill();
+    void
+    StopSendingMessagesToChild()
+    {
+      mIPCClosed = true;
+    }
 
     OfflineCacheUpdateParent(uint32_t aAppId, bool aIsInBrowser);
     ~OfflineCacheUpdateParent();
 
-    virtual void ActorDestroy(ActorDestroyReason why);
+    virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
 private:
-    void RefcountHitZero();
     bool mIPCClosed;
 
     bool     mIsInBrowserElement;
     uint32_t mAppId;
 };
 
 } // namespace docshell
 } // namespace mozilla
--- a/uriloader/prefetch/POfflineCacheUpdate.ipdl
+++ b/uriloader/prefetch/POfflineCacheUpdate.ipdl
@@ -16,13 +16,13 @@ protocol POfflineCacheUpdate
   manager PBrowser;
 
 parent:
   __delete__();
 
 child:
   NotifyStateEvent(uint32_t stateEvent, uint64_t byteProgress);
   AssociateDocuments(nsCString cacheGroupId, nsCString cacheClientId);
-  Finish(bool succeded, bool isUpgrate);
+  Finish(bool succeeded, bool isUpgrade);
 };
 
 }
 }