Bug 1216972 - OS.File AsyncShutdown for content processes. r=froydnj, a=ritu
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Thu, 19 Nov 2015 00:11:14 +0100
changeset 305781 af103a570400af6434e64d6e0f9632abef2ea5cd
parent 305780 9a72cc4433561be18f371c6e7aa8068e9aed4d78
child 305782 94fb54fd5330fad25ebb2b76c6389b02430f1d20
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 - OS.File AsyncShutdown for content processes. r=froydnj, a=ritu
toolkit/components/osfile/modules/osfile_async_front.jsm
--- a/toolkit/components/osfile/modules/osfile_async_front.jsm
+++ b/toolkit/components/osfile/modules/osfile_async_front.jsm
@@ -1458,21 +1458,26 @@ this.OS.Path = Path;
 
 // Returns a resolved promise when all the queued operation have been completed.
 Object.defineProperty(OS.File, "queue", {
   get: function() {
     return Scheduler.queue;
   }
 });
 
+// `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 = Components.classes["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
+
 /**
  * Shutdown barriers, to let clients register to be informed during shutdown.
  */
 var Barriers = {
-  profileBeforeChange: new AsyncShutdown.Barrier("OS.File: Waiting for clients before profile-before-shutdown"),
   shutdown: new AsyncShutdown.Barrier("OS.File: Waiting for clients before full shutdown"),
   /**
    * Return the shutdown state of OS.File
    */
   getDetails: function() {
     let result = {
       launched: Scheduler.launched,
       shutdown: Scheduler.shutdown,
@@ -1490,30 +1495,40 @@ var Barriers = {
       if (result[key] && typeof result[key][0] == "number") {
         result[key][0] = Date(result[key][0]);
       }
     }
     return result;
   }
 };
 
-File.profileBeforeChange = Barriers.profileBeforeChange.client;
-File.shutdown = Barriers.shutdown.client;
+function setupShutdown(phaseName) {
+  Barriers[phaseName] = new AsyncShutdown.Barrier(`OS.File: Waiting for clients before ${phaseName}`),
+  File[phaseName] = Barriers[phaseName].client;
+
+  // Auto-flush OS.File during `phaseName`. This ensures that any I/O
+  // that has been queued *before* `phaseName` is properly completed.
+  // To ensure that I/O queued *during* `phaseName` change is completed,
+  // clients should register using AsyncShutdown.addBlocker.
+  AsyncShutdown[phaseName].addBlocker(
+    `OS.File: flush I/O queued before ${phaseName}`,
+    Task.async(function*() {
+      // Give clients a last chance to enqueue requests.
+      yield Barriers[phaseName].wait({crashAfterMS: null});
 
-// Auto-flush OS.File during profile-before-change. This ensures that any I/O
-// that has been queued *before* profile-before-change is properly completed.
-// To ensure that I/O queued *during* profile-before-change is completed,
-// clients should register using AsyncShutdown.addBlocker.
-AsyncShutdown.profileBeforeChange.addBlocker(
-  "OS.File: flush I/O queued before profile-before-change",
-  Task.async(function*() {
-    // Give clients a last chance to enqueue requests.
-    yield Barriers.profileBeforeChange.wait({crashAfterMS: null});
+      // Wait until all currently enqueued requests are completed.
+      yield Scheduler.queue;
+    }),
+    () => {
+      let details = Barriers.getDetails();
+      details.clients = Barriers[phaseName].state;
+      return details;
+    }
+  );
+}
 
-    // Wait until all currently enqueued requests are completed.
-    yield Scheduler.queue;
-  }),
-  () => {
-    let details = Barriers.getDetails();
-    details.clients = Barriers.profileBeforeChange.state;
-    return details;
-  }
-);
+
+if (isContent) {
+  setupShutdown("contentChildShutdown");
+} else {
+  setupShutdown("profileBeforeChange")
+}
+File.shutdown = Barriers.shutdown.client;