Bug 874425 - Ensure that we never return an negative duration. r=froydnj, a=test-only
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Fri, 23 Aug 2013 10:06:33 -0400
changeset 148453 50cb228bb2f097a519b2301c255354a86da65ed6
parent 148452 f83885316c05290eadd60f0dc690a201a98302e5
child 148454 bb7690aa31da73270eb50c6d72eb071db81e02a5
push id2809
push userryanvm@gmail.com
push dateTue, 27 Aug 2013 13:36:39 +0000
treeherdermozilla-beta@650564aff1e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj, test-only
bugs874425
milestone24.0
Bug 874425 - Ensure that we never return an negative duration. r=froydnj, a=test-only
toolkit/components/osfile/osfile_async_front.jsm
toolkit/components/osfile/tests/mochi/main_test_osfile_async.js
--- a/toolkit/components/osfile/osfile_async_front.jsm
+++ b/toolkit/components/osfile/osfile_async_front.jsm
@@ -130,16 +130,21 @@ let Scheduler = {
           !("outExecutionDuration" in options)) {
           return data.ok;
         }
         // If data.durationMs is not present, return data.ok (there was an
         // exception applying the method).
         if (!("durationMs" in data)) {
           return data.ok;
         }
+        // Bug 874425 demonstrates that two successive calls to Date.now()
+        // can actually produce an interval with negative duration.
+        // We assume that this is due to an operation that is so short
+        // that Date.now() is not monotonic, so we round this up to 0.
+        let durationMs = Math.max(0, data.durationMs);
         // Accumulate (or initialize) outExecutionDuration
         if (typeof options.outExecutionDuration == "number") {
           options.outExecutionDuration += data.durationMs;
         } else {
           options.outExecutionDuration = data.durationMs;
         }
         return data.ok;
       },
--- a/toolkit/components/osfile/tests/mochi/main_test_osfile_async.js
+++ b/toolkit/components/osfile/tests/mochi/main_test_osfile_async.js
@@ -951,16 +951,17 @@ let test_system_shutdown = maketest("sys
   });
 });
 
 /**
  * Test optional duration reporting that can be used for telemetry.
  */
 let test_duration = maketest("duration", function duration(test) {
   return Task.spawn(function() {
+    Services.prefs.setBoolPref("toolkit.osfile.log", true);
     // Options structure passed to a OS.File copy method.
     let copyOptions = {
       // This field should be overridden with the actual duration
       // measurement.
       outExecutionDuration: null
     };
     let currentDir = yield OS.File.getCurrentDirectory();
     let pathSource = OS.Path.join(currentDir, EXISTING_FILE);
@@ -1026,17 +1027,17 @@ let test_duration = maketest("duration",
       tmpPath: tmpPath
     };
     backupDuration = writeAtomicOptions.outExecutionDuration;
 
     yield OS.File.writeAtomic(pathDest, contents, writeAtomicOptions);
     test.ok(copyOptions.outExecutionDuration >= backupDuration, "duration has increased 3");
     OS.File.remove(pathDest);
 
-    Services.prefs.setBoolPref("toolkit.osfile.log", true);
     OS.Shared.TEST = true;
 
     // Testing an operation that doesn't take arguments at all
     let file = yield OS.File.open(pathSource);
     yield file.stat();
     yield file.close();
+    Services.prefs.setBoolPref("toolkit.osfile.log", false);
   });
 });