Bug 1008148 - Use AsyncShutdown for PageThumbsStorage.wipe(). r=ttaubert a=sylvestre
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Sun, 18 May 2014 16:07:00 +0200
changeset 192379 8d180eb195d223e670e0f545cf4e9b2be47a730d
parent 192378 89929fdc95a7965726778f7c91575a84c6e5b787
child 192380 c32d46efa75731ea1d4d9a57c0dd75845df3218a
push id3592
push userttaubert@mozilla.com
push dateSun, 25 May 2014 18:54:23 +0000
treeherdermozilla-beta@8d180eb195d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersttaubert, sylvestre
bugs1008148
milestone30.0
Bug 1008148 - Use AsyncShutdown for PageThumbsStorage.wipe(). r=ttaubert a=sylvestre
toolkit/components/thumbnails/PageThumbs.jsm
--- a/toolkit/components/thumbnails/PageThumbs.jsm
+++ b/toolkit/components/thumbnails/PageThumbs.jsm
@@ -62,16 +62,18 @@ XPCOMUtils.defineLazyGetter(this, "gUnic
   converter.charset = 'utf8';
   return converter;
 });
 
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
   "resource://gre/modules/Deprecated.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
+  "resource://gre/modules/AsyncShutdown.jsm");
 
 /**
  * Utilities for dealing with promises and Task.jsm
  */
 const TaskUtils = {
   /**
    * Add logging to a promise.
    *
@@ -600,19 +602,54 @@ this.PageThumbsStorage = {
     return PageThumbsWorker.post("remove", [this.getFilePathForURL(aURL)]);
   },
 
   /**
    * Remove all thumbnails, off the main thread.
    *
    * @return {Promise}
    */
-  wipe: function Storage_wipe() {
-    return PageThumbsWorker.post("wipe", [this.path]);
-  },
+  wipe: Task.async(function* Storage_wipe() {
+    //
+    // This operation may be launched during shutdown, so we need to
+    // take a few precautions to ensure that:
+    //
+    // 1. it is not interrupted by shutdown, in which case we
+    //    could be leaving privacy-sensitive files on disk;
+    // 2. it is not launched too late during shutdown, in which
+    //    case this could cause shutdown freezes (see bug 1005487,
+    //    which will eventually be fixed by bug 965309)
+    //
+
+    let blocker = () => promise;
+
+    // The following operation will rise an error if we have already
+    // reached profileBeforeChange, in which case it is too late
+    // to clear the thumbnail wipe.
+    AsyncShutdown.profileBeforeChange.addBlocker(
+      "PageThumbs: removing all thumbnails",
+      blocker);
+
+    // Start the work only now that `profileBeforeChange` has had
+    // a chance to throw an error.
+
+    let promise = PageThumbsWorker.post("wipe", [this.path]);
+    try {
+      yield promise;
+    }  finally {
+       // Generally, we will be done much before profileBeforeChange,
+       // so let's not hoard blockers.
+       if ("removeBlocker" in AsyncShutdown.profileBeforeChange) {
+         // `removeBlocker` was added with bug 985655. In the interest
+         // of backporting, let's degrade gracefully if `removeBlocker`
+         // doesn't exist.
+         AsyncShutdown.profileBeforeChange.removeBlocker(blocker);
+       }
+    }
+  }),
 
   fileExistsForURL: function Storage_fileExistsForURL(aURL) {
     return PageThumbsWorker.post("exists", [this.getFilePathForURL(aURL)]);
   },
 
   isFileRecentForURL: function Storage_isFileRecentForURL(aURL) {
     return PageThumbsWorker.post("isFileRecent",
                                  [this.getFilePathForURL(aURL),