Bug 325418. When a repeating timer at interval X is reinitialized for interval Y, the next firing after that is incorrectly after time X+Y. r=bzbarsky
authorMichael Kraft <morac99-firefox2@yahoo.com>
Wed, 02 Nov 2011 23:46:08 -0400
changeset 79652 fdb29823b1d4
parent 79651 2ab1c36d6e27
child 79653 8df7a753bea0
push id21418
push usermak77@bonardo.net
push dateThu, 03 Nov 2011 14:57:14 +0000
treeherdermozilla-central@6cbeabc07c59 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs325418
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 325418. When a repeating timer at interval X is reinitialized for interval Y, the next firing after that is incorrectly after time X+Y. r=bzbarsky
xpcom/tests/unit/test_bug325418.js
xpcom/tests/unit/xpcshell.ini
xpcom/threads/nsTimerImpl.cpp
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/unit/test_bug325418.js
@@ -0,0 +1,32 @@
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+var timer;
+const start_time = (new Date()).getTime();
+const expected_time = 1;
+
+var observer = {
+  observe: function(subject, topic, data) {
+    if (topic == "timer-callback") {
+      var stop_time = (new Date()).getTime();
+      // expected time may not be exact so convert to seconds and round down.
+      var result = Math.round((stop_time - start_time) / 1000);
+      do_check_true(result, expected_time);
+
+      do_test_finished();
+
+      timer.cancel();
+      timer = null;
+    }
+  }
+};
+
+function run_test() {
+  do_test_pending();
+
+  timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+  // Start a 5 second timer, than cancel it and start a 1 second timer.
+  timer.init(observer, 5000, timer.TYPE_REPEATING_PRECISE);
+  timer.cancel();
+  timer.init(observer, 1000, timer.TYPE_REPEATING_PRECISE);
+}
\ No newline at end of file
--- a/xpcom/tests/unit/xpcshell.ini
+++ b/xpcom/tests/unit/xpcshell.ini
@@ -1,13 +1,14 @@
 [DEFAULT]
 head = head_xpcom.js
 tail = 
 
 [test_bug121341.js]
+[test_bug325418.js]
 [test_bug332389.js]
 [test_bug333505.js]
 [test_bug364285-1.js]
 # Bug 676998: test fails consistently on Android
 fail-if = os == "android"
 [test_bug374754.js]
 [test_bug476919.js]
 # Bug 676998: test fails consistently on Android
--- a/xpcom/threads/nsTimerImpl.cpp
+++ b/xpcom/threads/nsTimerImpl.cpp
@@ -217,16 +217,17 @@ nsresult nsTimerImpl::InitCommon(PRUint3
    * checking its list for this timer.  It's safe to test mArmed even though
    * it might be cleared on another thread in the next cycle (or even already
    * be cleared by another CPU whose store hasn't reached our CPU's cache),
    * because RemoveTimer is idempotent.
    */
   if (mArmed)
     gThread->RemoveTimer(this);
   mCanceled = false;
+  mTimeout = TimeStamp();
   mGeneration = PR_ATOMIC_INCREMENT(&gGenerator);
 
   mType = (PRUint8)aType;
   SetDelayInternal(aDelay);
 
   return gThread->AddTimer(this);
 }