Bug 1253204 - Don't abort shutdown on plugins sanitization. r=mak a=ritu
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Fri, 04 Mar 2016 16:11:21 +0100
changeset 323391 45c68ee48929e1e9d300037347658d05a312e556
parent 323390 3bb19c9730afdd2501d08c88cd410fd04bd71c38
child 323392 3228c0e5b050acaf9b16b41ba2ce51603356b1bb
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak, ritu
bugs1253204
milestone47.0a2
Bug 1253204 - Don't abort shutdown on plugins sanitization. r=mak a=ritu MozReview-Commit-ID: 5bub8n8cCsZ
browser/base/content/sanitize.js
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -273,26 +273,49 @@ Sanitizer.prototype = {
           let mediaMgr = Components.classes["@mozilla.org/mediaManagerService;1"]
                                    .getService(Ci.nsIMediaManagerService);
           mediaMgr.sanitizeDeviceIds(range && range[0]);
         } catch (ex) {
           seenException = ex;
         }
 
         // Clear plugin data.
+        // As evidenced in bug 1253204, clearing plugin data can sometimes be
+        // very, very long, for mysterious reasons. Unfortunately, this is not
+        // something actionable by Mozilla, so crashing here serves no purpose.
+        //
+        // For this reason, instead of waiting for sanitization to always
+        // complete, we introduce a soft timeout. Once this timeout has
+        // elapsed, we proceed with the shutdown of Firefox.
+        let promiseClearPluginCookies;
         TelemetryStopwatch.start("FX_SANITIZE_PLUGINS", refObj);
         try {
-          yield this.promiseClearPluginCookies(range);
+          // We don't want to wait for this operation to complete...
+          promiseClearPluginCookies = this.promiseClearPluginCookies(range);
+
+          //... at least, not for more than 10 seconds.
+          yield Promise.race([
+            promiseClearPluginCookies,
+            new Promise(resolve => setTimeout(resolve, 10000 /* 10 seconds */))
+          ]);
         } catch (ex) {
           seenException = ex;
-        } finally {
-          TelemetryStopwatch.finish("FX_SANITIZE_PLUGINS", refObj);
         }
 
-        TelemetryStopwatch.finish("FX_SANITIZE_COOKIES", refObj);
+        // Detach waiting for plugin cookies to be cleared.
+        promiseClearPluginCookies.catch(() => {
+          // If this exception is raised before the soft timeout, it
+          // will appear in `seenException`. Otherwise, it's too late
+          // to do anything about it.
+        }).then(() => {
+          // Finally, update statistics.
+          TelemetryStopwatch.finish("FX_SANITIZE_PLUGINS", refObj);
+          TelemetryStopwatch.finish("FX_SANITIZE_COOKIES", refObj);
+        });
+
         if (seenException) {
           throw seenException;
         }
       }),
 
       promiseClearPluginCookies: Task.async(function* (range) {
         const FLAG_CLEAR_ALL = Ci.nsIPluginHost.FLAG_CLEAR_ALL;
         let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);