From 9f805f495878e175d1b4112ed4af0080775e747a Mon Sep 17 00:00:00 2001 From: Steve Bjorg Date: Thu, 30 Jul 2015 10:29:22 -0700 Subject: [PATCH] Code changes from code review. --- .../Tasking/TaskTimerFactory.cs | 4 ++- src/mindtouch.dream/system/GlobalClock.cs | 28 +++++++++++-------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/mindtouch.dream/Tasking/TaskTimerFactory.cs b/src/mindtouch.dream/Tasking/TaskTimerFactory.cs index fc60ef9..30a4f24 100644 --- a/src/mindtouch.dream/Tasking/TaskTimerFactory.cs +++ b/src/mindtouch.dream/Tasking/TaskTimerFactory.cs @@ -321,10 +321,12 @@ public class TaskTimerStatistics { } } + // BUGBUGBUG (arnec): we don't actually do anything with timeout, but let every timer take + // an indefinite time. // check if any timers were gathered for immediate execution if(timers != null) { foreach(var entry in timers) { - entry.Key.ExecuteNow(entry.Value); + entry.Key.Execute(entry.Value); } } _running = false; diff --git a/src/mindtouch.dream/system/GlobalClock.cs b/src/mindtouch.dream/system/GlobalClock.cs index bc21a9f..b0c187f 100644 --- a/src/mindtouch.dream/system/GlobalClock.cs +++ b/src/mindtouch.dream/system/GlobalClock.cs @@ -63,7 +63,7 @@ public static class GlobalClock { } //--- Class Properties --- - public static DateTime UtcNow { get { return (((DateTime?)_suspendedTime) ?? DateTime.UtcNow) + TimeSpan.FromMilliseconds(_timeOffset); } } + public static DateTime UtcNow { get { return ((DateTime?)_suspendedTime) ?? (DateTime.UtcNow + TimeSpan.FromMilliseconds(_timeOffset)); } } //--- Class Methods --- @@ -127,22 +127,25 @@ public static class GlobalClock { /// Optional callback to prematurely cancel the fast-fwoard operation. /// DO NOT USE FOR PRODUCTION CODE!!! public static DateTime FastForward(TimeSpan time, Func cancelFastForward = null) { - if(time < TimeSpan.Zero) { - throw new ArgumentException("time cannot be negative"); + + // TODO (2015-07-30, steveb): add flag to detect if this code is running in production and throw an exception if it is! + + if(time <= TimeSpan.Zero) { + throw new ArgumentException("time must be positive"); } lock(_syncRoot) { var timeMilliseconds = (int)time.TotalMilliseconds; - var intervalMilliseconds = _intervalMilliseconds / 2; - while(timeMilliseconds >= intervalMilliseconds) { - Interlocked.Add(ref _timeOffset, intervalMilliseconds); + var intervalMilliseconds = _intervalMilliseconds; + do { + var elapsed = Math.Min(timeMilliseconds, intervalMilliseconds); + Interlocked.Add(ref _timeOffset, elapsed); var now = UtcNow; - MasterTick(now, TimeSpan.FromMilliseconds(intervalMilliseconds), true); + MasterTick(now, TimeSpan.FromMilliseconds(elapsed), true); if((cancelFastForward != null) && cancelFastForward()) { return now; } - timeMilliseconds -= intervalMilliseconds; - } - Interlocked.Add(ref _timeOffset, timeMilliseconds); + timeMilliseconds -= elapsed; + } while(timeMilliseconds > 0); return UtcNow; } } @@ -153,8 +156,11 @@ public static class GlobalClock { /// Object that when disposed resumes the global clock. /// DO NOT USE FOR PRODUCTION CODE!!! public static IDisposable Suspend() { + + // TODO (2015-07-30, steveb): add flag to detect if this code is running in production and throw an exception if it is! + Monitor.Enter(_syncRoot); - var suspendedTime = Interlocked.Exchange(ref _suspendedTime, UtcNow); + var suspendedTime = Interlocked.Exchange(ref _suspendedTime, (DateTime?)UtcNow); return new DisposeCallback(() => { Interlocked.Exchange(ref _suspendedTime, suspendedTime); Monitor.Exit(_syncRoot);