Skip to content
This repository has been archived by the owner on Apr 30, 2021. It is now read-only.

Commit

Permalink
Added GlobalClock.Suspend() to stop time when needed.
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorg committed Jul 28, 2015
1 parent 2d8fa66 commit 0b5013e
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/mindtouch.dream/mindtouch.dream.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
<Compile Include="dream\RegistrationInspector.cs" />
<Compile Include="Extensions\ReflectionEx.cs" />
<Compile Include="Numeric.cs" />
<Compile Include="system\DisposeCallback.cs" />
<Compile Include="system\GitBranchAttribute.cs" />
<Compile Include="system\GitRevisionAttribute.cs" />
<Compile Include="system\GitUriAttribute.cs" />
Expand Down
50 changes: 50 additions & 0 deletions src/mindtouch.dream/system/DisposeCallback.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* MindTouch Dream - a distributed REST framework
* Copyright (C) 2006-2014 MindTouch, Inc.
* www.mindtouch.com oss@mindtouch.com
*
* For community documentation and downloads visit mindtouch.com;
* please review the licensing section.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace System {

/// <summary>
/// Class to trigger a callback when Dispose() is called.
/// </summary>
public class DisposeCallback : IDisposable {

//--- Fields ---
private readonly Action _callback;
private bool _disposed;

//--- Constructors ---
public DisposeCallback(Action callback) {
if(callback == null) {
throw new ArgumentNullException("callback");
}
_callback = callback;
}

//--- Methods ---
public void Dispose() {
if(_disposed) {
throw new ObjectDisposedException("DisposeCallback");
}
_disposed = true;
_callback();
}
}
}
17 changes: 16 additions & 1 deletion src/mindtouch.dream/system/GlobalClock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public static class GlobalClock {
private static readonly ManualResetEvent _stopped = new ManualResetEvent(false);
private static NamedClockCallback[] _callbacks = new NamedClockCallback[INITIAL_CALLBACK_CAPACITY];
private static readonly int _intervalMilliseconds;
private static object _suspendedTime;
private static int _timeOffset;

//--- Class Constructor ---
Expand All @@ -62,7 +63,7 @@ public static class GlobalClock {
}

//--- Class Properties ---
public static DateTime UtcNow { get { return DateTime.UtcNow + TimeSpan.FromMilliseconds(_timeOffset); } }
public static DateTime UtcNow { get { return (((DateTime?)_suspendedTime) ?? DateTime.UtcNow) + TimeSpan.FromMilliseconds(_timeOffset); } }

//--- Class Methods ---

Expand Down Expand Up @@ -146,6 +147,20 @@ public static class GlobalClock {
}
}

/// <summary>
/// Suspend the global clock from progressing.
/// </summary>
/// <returns>Object that when disposed resumes the global clock.</returns>
/// <remarks>DO NOT USE FOR PRODUCTION CODE!!!</remarks>
public static IDisposable Suspend() {
Monitor.Enter(_syncRoot);
var suspendedTime = Interlocked.Exchange(ref _suspendedTime, UtcNow);
return new DisposeCallback(() => {
Interlocked.Exchange(ref _suspendedTime, suspendedTime);
Monitor.Exit(_syncRoot);
});
}

internal static bool Shutdown(TimeSpan timeout) {

// stop the thread timer
Expand Down

0 comments on commit 0b5013e

Please sign in to comment.