Bug 1216972 - AsyncShutdown for content processes. r=froydnj, a=ritu
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Thu, 19 Nov 2015 00:09:58 +0100
changeset 305780 9a72cc4433561be18f371c6e7aa8068e9aed4d78
parent 305779 afefb6c948e63baf5db0f299971d9291d39ef488
child 305781 af103a570400af6434e64d6e0f9632abef2ea5cd
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj, ritu
bugs1216972
milestone44.0a2
Bug 1216972 - AsyncShutdown for content processes. r=froydnj, a=ritu
toolkit/components/asyncshutdown/AsyncShutdown.jsm
toolkit/components/asyncshutdown/nsAsyncShutdown.js
toolkit/components/asyncshutdown/nsIAsyncShutdown.idl
--- a/toolkit/components/asyncshutdown/AsyncShutdown.jsm
+++ b/toolkit/components/asyncshutdown/AsyncShutdown.jsm
@@ -61,16 +61,22 @@ Object.defineProperty(this, "gCrashRepor
       return this.gCrashReporter = reporter;
     } catch (ex) {
       return this.gCrashReporter = null;
     }
   },
   configurable: true
 });
 
+// `true` if this is a content process, `false` otherwise.
+// It would be nicer to go through `Services.appInfo`, but some tests need to be
+// able to replace that field with a custom implementation before it is first
+// called.
+const isContent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
+
 // Display timeout warnings after 10 seconds
 const DELAY_WARNING_MS = 10 * 1000;
 
 
 // Crash the process if shutdown is really too long
 // (allowing for sleep).
 const PREF_DELAY_CRASH_MS = "toolkit.asyncshutdown.crash_timeout";
 var DELAY_CRASH_MS = 60 * 1000; // One minute
@@ -974,18 +980,29 @@ Barrier.prototype = Object.freeze({
 
 
 
 // List of well-known phases
 // Ideally, phases should be registered from the component that decides
 // when they start/stop. For compatibility with existing startup/shutdown
 // mechanisms, we register a few phases here.
 
-this.AsyncShutdown.profileChangeTeardown = getPhase("profile-change-teardown");
-this.AsyncShutdown.profileBeforeChange = getPhase("profile-before-change");
-this.AsyncShutdown.placesClosingInternalConnection = getPhase("places-will-close-connection");
-this.AsyncShutdown.sendTelemetry = getPhase("profile-before-change2");
+// Parent process
+if (!isContent) {
+  this.AsyncShutdown.profileChangeTeardown = getPhase("profile-change-teardown");
+  this.AsyncShutdown.profileBeforeChange = getPhase("profile-before-change");
+  this.AsyncShutdown.placesClosingInternalConnection = getPhase("places-will-close-connection");
+  this.AsyncShutdown.sendTelemetry = getPhase("profile-before-change2");
+}
+
+
+// Content process
+if (isContent) {
+  this.AsyncShutdown.contentChildShutdown = getPhase("content-child-shutdown");
+}
+
+// All processes
 this.AsyncShutdown.webWorkersShutdown = getPhase("web-workers-shutdown");
 this.AsyncShutdown.xpcomThreadsShutdown = getPhase("xpcom-threads-shutdown");
 
 this.AsyncShutdown.Barrier = Barrier;
 
 Object.freeze(this.AsyncShutdown);
--- a/toolkit/components/asyncshutdown/nsAsyncShutdown.js
+++ b/toolkit/components/asyncshutdown/nsAsyncShutdown.js
@@ -221,27 +221,35 @@ nsAsyncShutdownBarrier.prototype = {
   QueryInterface :  XPCOMUtils.generateQI([Ci.nsIAsyncShutdownBarrier]),
   classID:          Components.ID("{29a0e8b5-9111-4c09-a0eb-76cd02bf20fa}"),
 };
 
 function nsAsyncShutdownService() {
   // Cache for the getters
 
   for (let _k of
-   ["profileBeforeChange",
+   [// Parent process
+    "profileBeforeChange",
     "profileChangeTeardown",
     "sendTelemetry",
+
+    // Child processes
+    "contentChildShutdown",
+
+    // All processes
     "webWorkersShutdown",
-    "xpcomThreadsShutdown"]) {
+    "xpcomThreadsShutdown",
+    ]) {
     let k = _k;
     Object.defineProperty(this, k, {
       configurable: true,
       get: function() {
         delete this[k];
-        let result = new nsAsyncShutdownClient(AsyncShutdown[k]);
+        let wrapped = AsyncShutdown[k]; // May be undefined, if we're on the wrong process.
+        let result = wrapped ? new nsAsyncShutdownClient(wrapped) : undefined;
         Object.defineProperty(this, k, {
           value: result
         });
         return result;
       }
     });
   }
 
@@ -261,9 +269,8 @@ nsAsyncShutdownService.prototype = {
 };
 
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
     nsAsyncShutdownService,
     nsAsyncShutdownBarrier,
     nsAsyncShutdownClient,
 ]);
-
--- a/toolkit/components/asyncshutdown/nsIAsyncShutdown.idl
+++ b/toolkit/components/asyncshutdown/nsIAsyncShutdown.idl
@@ -155,53 +155,61 @@ interface nsIAsyncShutdownBarrier: nsISu
    * The callback always receives NS_OK.
    */
   void wait(in nsIAsyncShutdownCompletionCallback aOnReady);
 };
 
 /**
  * A service that allows registering shutdown-time dependencies.
  */
-[scriptable, uuid(8a9a0859-0404-4d50-9e76-10a4f56dfb51)]
+[scriptable, uuid(10f51032-dcc9-4732-bec0-c0b7d6596622)]
 interface nsIAsyncShutdownService: nsISupports {
   /**
    * Create a new barrier.
    *
    * By convention, the name should respect the following format:
    * "MyModuleName: Doing something while it's time"
    * e.g.
    * "OS.File: Waiting for clients to flush before shutting down"
    *
    * This attribute is uploaded as part of crash reports.
    */
   nsIAsyncShutdownBarrier makeBarrier(in AString aName);
 
-  // Barriers for global shutdown stages
+
+  // Barriers for global shutdown stages in the parent process.
 
   /**
    * Barrier for notification profile-before-change.
    */
   readonly attribute nsIAsyncShutdownClient profileBeforeChange;
 
   /**
    * Barrier for notification profile-change-teardown.
    */
   readonly attribute nsIAsyncShutdownClient profileChangeTeardown;
 
   /**
    * Barrier for notification profile-before-change2.
    */
   readonly attribute nsIAsyncShutdownClient sendTelemetry;
 
+  // Barriers for global shutdown stages in the content processes.
+
+  readonly attribute nsIAsyncShutdownClient contentChildShutdown;
+
+  // Barriers for global shutdown stages in all processes.
+
   /**
    * Barrier for notification web-workers-shutdown.
    */
   readonly attribute nsIAsyncShutdownClient webWorkersShutdown;
 
   /**
    * Barrier for notification xpcom-threads-shutdown.
    */
   readonly attribute nsIAsyncShutdownClient xpcomThreadsShutdown;
+
 };
 
 %{C++
 #define NS_ASYNCSHUTDOWNSERVICE_CONTRACTID "@mozilla.org/async-shutdown-service;1"
 %}