From a3a5e4a6f548bf8b9d2874a5d6578c8364a1984f Mon Sep 17 00:00:00 2001 From: Simon Ochsenreither Date: Wed, 11 Dec 2013 14:05:42 +0100 Subject: SI-7546 Use likely monotonic clock source for durations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit System.currentTimeMillis is affected by wall-clock time, which means things can appear to jump back in time. Use System.nanoTime which is more likely¹ to be monotonic instead. ¹ See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6458294 "nanoTime affected by system clock change on Linux (RH9) or in general lacks monotonicity". --- src/library/scala/concurrent/SyncVar.scala | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/library') diff --git a/src/library/scala/concurrent/SyncVar.scala b/src/library/scala/concurrent/SyncVar.scala index 76d21c3dbf..d5dc3d7e3f 100644 --- a/src/library/scala/concurrent/SyncVar.scala +++ b/src/library/scala/concurrent/SyncVar.scala @@ -8,6 +8,8 @@ package scala.concurrent +import java.util.concurrent.TimeUnit + /** A class to provide safe concurrent access to a mutable cell. * All methods are synchronized. * @@ -23,14 +25,16 @@ class SyncVar[A] { value.get } - /** Waits `timeout` millis. If `timeout <= 0` just returns 0. If the system clock - * went backward, it will return 0, so it never returns negative results. - */ + /** Waits `timeout` millis. If `timeout <= 0` just returns 0. + * It never returns negative results. + */ private def waitMeasuringElapsed(timeout: Long): Long = if (timeout <= 0) 0 else { - val start = System.currentTimeMillis + val start = System.nanoTime() wait(timeout) - val elapsed = System.currentTimeMillis - start - if (elapsed < 0) 0 else elapsed + val elapsed = System.nanoTime() - start + // nanoTime should be monotonic, but it's not possible to rely on that. + // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6458294. + if (elapsed < 0) 0 else TimeUnit.NANOSECONDS.toMillis(elapsed) } /** Waits for this SyncVar to become defined at least for -- cgit v1.2.3