Bug 1350471 - Provide an unregisterTimer function for nsIUpdateTimerManager. r=mossop, a=lizzard
authorRobert Helmer <rhelmer@mozilla.com>
Sun, 26 Mar 2017 00:56:46 -0700
changeset 379367 91ca571410f212407aa7abacef30d753d31e3821
parent 379366 c92e96316678cd89053d4016e5428274a7315d4d
child 379368 f7dcb07ca4185b53afa16a692e0a9fcaedbc3b4b
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmossop, lizzard
bugs1350471
milestone53.0
Bug 1350471 - Provide an unregisterTimer function for nsIUpdateTimerManager. r=mossop, a=lizzard MozReview-Commit-ID: HMcaqXA3dJW
toolkit/components/timermanager/nsIUpdateTimerManager.idl
toolkit/components/timermanager/nsUpdateTimerManager.js
toolkit/components/timermanager/tests/unit/consumerNotifications.js
--- a/toolkit/components/timermanager/nsIUpdateTimerManager.idl
+++ b/toolkit/components/timermanager/nsIUpdateTimerManager.idl
@@ -46,9 +46,17 @@ interface nsIUpdateTimerManager : nsISup
    *   id         : the id that identifies the interval, used for persistence.
    *   preference : the preference to for timer interval. This value can be
    *                optional by specifying an empty string for the value.
    *   interval   : the default interval in seconds for the timer.
    */
   void registerTimer(in AString id,
                      in nsITimerCallback callback,
                      in unsigned long interval);
+
+  /**
+   * Unregister an existing interval from the timer manager.
+   *
+   * @param   id
+   *          An id that identifies the interval.
+   */
+  void unregisterTimer(in AString id);
 };
--- a/toolkit/components/timermanager/nsUpdateTimerManager.js
+++ b/toolkit/components/timermanager/nsUpdateTimerManager.js
@@ -325,15 +325,24 @@ TimerManager.prototype = {
     }
     this._timers[id] = {callback,
                         interval,
                         lastUpdateTime};
 
     this._ensureTimer(interval * 1000);
   },
 
+  unregisterTimer: function TM_unregisterTimer(id) {
+    LOG(`TimerManager:unregisterTimer - id: ${id}`);
+    if (id in this._timers) {
+      delete this._timers[id];
+    } else {
+      LOG(`TimerManager:registerTimer - Ignoring unregistration request for unknown id: ${id}`);
+    }
+  },
+
   classID: Components.ID("{B322A5C0-A419-484E-96BA-D7182163899F}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateTimerManager,
                                          Ci.nsITimerCallback,
                                          Ci.nsIObserver])
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TimerManager]);
--- a/toolkit/components/timermanager/tests/unit/consumerNotifications.js
+++ b/toolkit/components/timermanager/tests/unit/consumerNotifications.js
@@ -106,16 +106,24 @@ const TESTS = [ {
 }, {
   desc: "Test Timer Callback 9",
   timerID: "test9-update-timer",
   defaultInterval: CONSUMER_TIMER_INTERVAL,
   contractID: "@mozilla.org/test9/timercallback;1",
   classID: Components.ID("5136b201-d64c-4328-8cf1-1a63491cc117"),
   notified: false,
   lastUpdateTime: 0
+}, {
+  desc: "Test Timer Callback 10",
+  timerID: "test10-update-timer",
+  defaultInterval: CONSUMER_TIMER_INTERVAL,
+  contractID: "@mozilla.org/test9/timercallback;1",
+  classID: Components.ID("1f42bbb3-d116-4012-8491-3ec4797a97ee"),
+  notified: false,
+  lastUpdateTime: 0
 } ];
 
 var gUTM;
 var gNextFunc;
 
 XPCOMUtils.defineLazyServiceGetter(this, "gPref",
                                    "@mozilla.org/preferences-service;1",
                                    "nsIPrefBranch");
@@ -267,17 +275,17 @@ const gTest7Factory = {
   }
 };
 
 const gTest8TimerCallback = {
   notify: function T8CB_notify(aTimer) {
     TESTS[8].notified = true;
     TESTS[8].notifyTime = Date.now();
     do_execute_soon(function() {
-      check_test8thru9(gTest8TimerCallback);
+      check_test8thru10(gTest8TimerCallback);
     });
   },
   QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback])
 };
 
 const gTest8Factory = {
   createInstance: function T8F_createInstance(aOuter, aIID) {
     if (aOuter == null) {
@@ -287,22 +295,31 @@ const gTest8Factory = {
   }
 };
 
 const gTest9TimerCallback = {
   notify: function T9CB_notify(aTimer) {
     TESTS[9].notified = true;
     TESTS[9].notifyTime = Date.now();
     do_execute_soon(function() {
-      check_test8thru9(gTest9TimerCallback);
+      check_test8thru10(gTest9TimerCallback);
     });
   },
   QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback])
 };
 
+const gTest10TimerCallback = {
+  notify: function T9CB_notify(aTimer) {
+    // The timer should have been unregistered before this could
+    // be called.
+    do_throw("gTest10TimerCallback notify method should not have been called");
+  },
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback])
+};
+
 const gTest9Factory = {
   createInstance: function T9F_createInstance(aOuter, aIID) {
     if (aOuter == null) {
       return gTest9TimerCallback.QueryInterface(aIID);
     }
     throw Cr.NS_ERROR_NO_AGGREGATION;
   }
 };
@@ -464,33 +481,36 @@ function check_test0thru7() {
     gCatMan.deleteCategoryEntry(CATEGORY_UPDATE_TIMER, entry, false);
   }
 
   entries = gCatMan.enumerateCategory(CATEGORY_UPDATE_TIMER);
   Assert.ok(!entries.hasMoreElements(),
             "no " + CATEGORY_UPDATE_TIMER + " categories should still be " +
             "registered");
 
-  do_execute_soon(run_test8thru9);
+  do_execute_soon(run_test8thru10);
 }
 
-function run_test8thru9() {
+function run_test8thru10() {
   gPref.setIntPref(PREF_BRANCH_LAST_UPDATE_TIME + TESTS[8].timerID, 1);
   gCompReg.registerFactory(TESTS[8].classID, TESTS[8].desc,
                            TESTS[8].contractID, gTest8Factory);
   gUTM.registerTimer(TESTS[8].timerID, gTest8TimerCallback,
                      TESTS[8].defaultInterval);
   gPref.setIntPref(PREF_BRANCH_LAST_UPDATE_TIME + TESTS[9].timerID, 1);
   gCompReg.registerFactory(TESTS[9].classID, TESTS[9].desc,
                            TESTS[9].contractID, gTest9Factory);
   gUTM.registerTimer(TESTS[9].timerID, gTest9TimerCallback,
                      TESTS[9].defaultInterval);
+  gUTM.registerTimer(TESTS[10].timerID, gTest10TimerCallback,
+                     TESTS[10].defaultInterval);
+  gUTM.unregisterTimer(TESTS[10].timerID);
 }
 
-function check_test8thru9(aTestTimerCallback) {
+function check_test8thru10(aTestTimerCallback) {
   aTestTimerCallback.timesCalled = (aTestTimerCallback.timesCalled || 0) + 1;
   if (aTestTimerCallback.timesCalled < 2) {
     return;
   }
 
   Assert.ok(TESTS[8].notified,
             "first registerTimer registered timer should have fired");