Bug 959886 - Handle offline cache updates in parent process after windows are being torn down in child processes. r=mayhemer.
authorBen Turner <bent.mozilla@gmail.com>
Wed, 15 Jan 2014 12:20:33 -0800
changeset 163824 c225b6041c389e08041c7f538464753addf7f919
parent 163821 605dc4d541a52bca93a8cff3eb6aa538b74622e5
child 163825 23f0f77a7353b9219bcfa8bc67280bb58cc338a9
push id26012
push userkwierso@gmail.com
push dateFri, 17 Jan 2014 01:12:33 +0000
treeherdermozilla-central@c040b200b336 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs959886
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 959886 - Handle offline cache updates in parent process after windows are being torn down in child processes. r=mayhemer.
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
@@ -273,16 +273,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;
 }
@@ -1638,42 +1646,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
@@ -232,21 +232,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);
 };
 
 }
 }