Bug 1103036 - Follow-up to initial patch; r=jchen
authorBill McCloskey <wmccloskey@mozilla.com>
Sat, 10 Jan 2015 13:39:33 -0500
changeset 223134 9d50f9865ed636c85de582b8d77b5b5d054fd497
parent 223133 818164d97da8d620836a5ff023e4a20fbbfae1f6
child 223135 5c4c5685381fc6511ef71d5ecf0c346833e9dbfd
push id28082
push usercbook@mozilla.com
push dateMon, 12 Jan 2015 10:44:52 +0000
treeherdermozilla-central@643589c3ef94 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjchen
bugs1103036
milestone37.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 1103036 - Follow-up to initial patch; r=jchen
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2491,21 +2491,20 @@ ContentChild::RecvAssociatePluginId(cons
 
 bool
 ContentChild::RecvShutdown()
 {
     nsCOMPtr<nsIObserverService> os = services::GetObserverService();
     if (os) {
         os->NotifyObservers(this, "content-child-shutdown", nullptr);
     }
-    // Let the parent know we're done and let it close the channel.
-    // Both sides will clean up even if an error occurs here.
-    MessageLoop::current()->PostTask(
-        FROM_HERE,
-        NewRunnableMethod(this, &ContentChild::SendFinishShutdown));
+
+    // Ignore errors here. If this fails, the parent will kill us after a
+    // timeout.
+    unused << SendFinishShutdown();
     return true;
 }
 
 PBrowserOrId
 ContentChild::GetBrowserOrId(TabChild* aTabChild)
 {
     if (!aTabChild ||
         this == aTabChild->Manager()) {
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1497,18 +1497,17 @@ ContentParent::TransformPreallocatedInto
 
 void
 ContentParent::ShutDownProcess(ShutDownMethod aMethod)
 {
     // Shutting down by sending a shutdown message works differently than the
     // other methods. We first call Shutdown() in the child. After the child is
     // ready, it calls FinishShutdown() on us. Then we close the channel.
     if (aMethod == SEND_SHUTDOWN_MESSAGE) {
-
-        if (SendShutdown()) {
+        if (mIPCOpen && SendShutdown()) {
             mShutdownPending = true;
         }
 
         // If call was not successful, the channel must have been broken
         // somehow, and we will clean up the error in ActorDestroy.
         return;
     }
 
@@ -1771,17 +1770,17 @@ ContentParent::ActorDestroy(ActorDestroy
 {
     if (mForceKillTask) {
         mForceKillTask->Cancel();
         mForceKillTask = nullptr;
     }
 
     // Signal shutdown completion regardless of error state,
     // so we can finish waiting in the xpcom-shutdown observer.
-    mShutdownComplete = true;
+    mIPCOpen = false;
 
     if (why == NormalShutdown && !mCalledClose) {
         // If we shut down normally but haven't called Close, assume somebody
         // else called Close on us. In that case, we still need to call
         // ShutDownProcess below to perform other necessary clean up.
         mCalledClose = true;
     }
 
@@ -1995,17 +1994,17 @@ ContentParent::InitializeMembers()
     mIsAlive = true;
     mSendPermissionUpdates = false;
     mSendDataStoreInfos = false;
     mCalledClose = false;
     mCalledCloseWithError = false;
     mCalledKillHard = false;
     mCreatedPairedMinidumps = false;
     mShutdownPending = false;
-    mShutdownComplete = false;
+    mIPCOpen = true;
 }
 
 ContentParent::ContentParent(mozIApplication* aApp,
                              ContentParent* aOpener,
                              bool aIsForBrowser,
                              bool aIsForPreallocated,
                              ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */,
                              bool aIsNuwaProcess /* = false */)
@@ -2740,25 +2739,25 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 NS_IMETHODIMP
 ContentParent::Observe(nsISupports* aSubject,
                        const char* aTopic,
                        const char16_t* aData)
 {
     if (!strcmp(aTopic, "xpcom-shutdown") && mSubprocess) {
-        if (mShutdownPending) {
-            // Wait for shutdown to complete, so that we receive any shutdown
-            // data (e.g. telemetry) from the child before we quit.
-            while (!mShutdownComplete) {
-                NS_ProcessNextEvent(nullptr, true);
-            }
-        } else {
-            // Just close the channel if we never tried shutting down.
-            ShutDownProcess(CLOSE_CHANNEL);
+        if (!mShutdownPending && mIPCOpen) {
+            ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
+        }
+
+        // Wait for shutdown to complete, so that we receive any shutdown
+        // data (e.g. telemetry) from the child before we quit.
+        // This loop terminate prematurely based on mForceKillTimer.
+        while (mIPCOpen) {
+            NS_ProcessNextEvent(nullptr, true);
         }
         NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
     }
 
     if (!mIsAlive || !mSubprocess)
         return NS_OK;
 
     // listening for memory pressure event
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -808,17 +808,17 @@ private:
 
     // These variables track whether we've called Close(), CloseWithError()
     // and KillHard() on our channel.
     bool mCalledClose;
     bool mCalledCloseWithError;
     bool mCalledKillHard;
     bool mCreatedPairedMinidumps;
     bool mShutdownPending;
-    bool mShutdownComplete;
+    bool mIPCOpen;
 
     friend class CrashReporterParent;
 
     nsRefPtr<nsConsoleService>  mConsoleService;
     nsConsoleService* GetConsoleService();
 
     nsDataHashtable<nsUint64HashKey, nsRefPtr<ParentIdleListener> > mIdleListeners;