Bug 1317587 - don't start scheduled sync after shutdown. r=rnewman
authorMark Hammond <mhammond@skippinet.com.au>
Tue, 15 Nov 2016 15:28:52 +1100
changeset 439696 b84a197304d6e5e6bcbcefc8c2bbedbc0053f2bd
parent 439695 5f5e46d71cbf98eb61db0e5e934fd5ed7efc6109
child 439697 860e550daed62b41081d5877039c5f5badce7712
push id36064
push userrthijssen@mozilla.com
push dateWed, 16 Nov 2016 13:38:27 +0000
reviewersrnewman
bugs1317587
milestone53.0a1
Bug 1317587 - don't start scheduled sync after shutdown. r=rnewman MozReview-Commit-ID: GSyWAUa1qyr
services/common/async.js
services/sync/modules/policies.js
--- a/services/common/async.js
+++ b/services/common/async.js
@@ -107,33 +107,49 @@ this.Async = {
       throw callback.value;
     }
 
     // Return the value passed to the callback.
     return callback.value;
   },
 
   /**
-   * Check if the app is still ready (not quitting).
+   * Check if the app is still ready (not quitting). Returns true, or throws an
+   * exception if not ready.
    */
   checkAppReady: function checkAppReady() {
     // Watch for app-quit notification to stop any sync calls
     Services.obs.addObserver(function onQuitApplication() {
       Services.obs.removeObserver(onQuitApplication, "quit-application");
       Async.checkAppReady = function() {
         let exception = Components.Exception("App. Quitting", Cr.NS_ERROR_ABORT);
         exception.appIsShuttingDown = true;
         throw exception;
       };
     }, "quit-application", false);
     // In the common case, checkAppReady just returns true
     return (Async.checkAppReady = function() { return true; })();
   },
 
   /**
+   * Check if the app is still ready (not quitting). Returns true if the app
+   * is ready, or false if it is being shut down.
+   */
+  isAppReady() {
+    try {
+      return Async.checkAppReady()
+    } catch (ex) {
+      if (!Async.isShutdownException(ex)) {
+        throw ex;
+      }
+    }
+    return false;
+  },
+
+  /**
    * Check if the passed exception is one raised by checkAppReady. Typically
    * this will be used in exception handlers to allow such exceptions to
    * make their way to the top frame and allow the app to actually terminate.
    */
   isShutdownException(exception) {
     return exception && exception.appIsShuttingDown === true;
   },
 
--- a/services/sync/modules/policies.js
+++ b/services/sync/modules/policies.js
@@ -396,16 +396,20 @@ SyncScheduler.prototype = {
       this._log.debug("Not initiating sync: Login status is " + Status.login);
 
       // If we're not syncing now, we need to schedule the next one.
       this._log.trace("Scheduling a sync at MASTER_PASSWORD_LOCKED_RETRY_INTERVAL");
       this.scheduleAtInterval(MASTER_PASSWORD_LOCKED_RETRY_INTERVAL);
       return;
     }
 
+    if (!Async.isAppReady()) {
+      this._log.debug("Not initiating sync: app is shutting down");
+      return;
+    }
     Utils.nextTick(this.service.sync, this.service);
   },
 
   /**
    * Set a timer for the next sync
    */
   scheduleNextSync: function scheduleNextSync(interval) {
     // If no interval was specified, use the current sync interval.