1 //------------------------------------------------------------------------------
2 // <copyright file="TimeoutTimer.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // Class used to manage timeouts in complex system operations.
8 // <owner current="true" primary="true">Microsoft</owner>
9 // <owner current="true" primary="false">Microsoft</owner>
10 //------------------------------------------------------------------------------
12 namespace System.Data.ProviderBase
15 using System.Data.Common;
16 using System.Diagnostics;
19 // Manages determining and tracking timeouts
22 // Call StartXXXXTimeout() to get a timer with the given expiration point
23 // Get remaining time in appropriate format to pass to subsystem timeouts
24 // Check for timeout via IsExpired for checks in managed code.
25 // Simply abandon to GC when done.
26 internal class TimeoutTimer
31 private long _timerExpire;
32 private bool _isInfiniteTimeout;
35 // Timeout-setting methods
38 // Get a new timer that will expire in the given number of seconds
39 // For input, a value of zero seconds indicates infinite timeout
40 internal static TimeoutTimer StartSecondsTimeout(int seconds)
42 //--------------------
43 // Preconditions: None (seconds must conform to SetTimeoutSeconds requirements)
45 //--------------------
47 var timeout = new TimeoutTimer();
48 timeout.SetTimeoutSeconds(seconds);
50 //---------------------
52 Debug.Assert(timeout != null); // Need a valid timeouttimer if no error
57 // Get a new timer that will expire in the given number of milliseconds
58 // No current need to support infinite milliseconds timeout
59 internal static TimeoutTimer StartMillisecondsTimeout(long milliseconds)
61 //--------------------
63 Debug.Assert(0 <= milliseconds);
65 //--------------------
67 var timeout = new TimeoutTimer();
68 timeout._timerExpire = checked(ADP.TimerCurrent() + (milliseconds * TimeSpan.TicksPerMillisecond));
69 timeout._isInfiniteTimeout = false;
71 //---------------------
73 Debug.Assert(timeout != null); // Need a valid timeouttimer if no error
79 // Methods for changing timeout
82 internal void SetTimeoutSeconds(int seconds)
84 //--------------------
86 Debug.Assert(0 <= seconds || InfiniteTimeout == seconds); // no need to support negative seconds at present
88 //--------------------
90 if (InfiniteTimeout == seconds)
92 _isInfiniteTimeout = true;
96 // Stash current time + timeout
97 _timerExpire = checked(ADP.TimerCurrent() + ADP.TimerFromSeconds(seconds));
98 _isInfiniteTimeout = false;
101 //---------------------
102 // Postconditions:None
105 //-------------------
106 // Timeout info properties
107 //-------------------
109 // Indicator for infinite timeout when starting a timer
110 internal static readonly long InfiniteTimeout = 0;
112 // Is this timer in an expired state?
113 internal bool IsExpired
117 return !IsInfinite && ADP.TimerHasExpired(_timerExpire);
121 // is this an infinite-timeout timer?
122 internal bool IsInfinite
126 return _isInfiniteTimeout;
130 // Special accessor for TimerExpire for use when thunking to legacy timeout methods.
131 internal long LegacyTimerExpire
135 return (_isInfiniteTimeout) ? Int64.MaxValue : _timerExpire;
139 // Returns milliseconds remaining trimmed to zero for none remaining
140 // and long.MaxValue for infinite
141 // This method should be prefered for internal calculations that are not
142 // yet common enough to code into the TimeoutTimer class itself.
143 internal long MillisecondsRemaining
147 //-------------------
148 // Preconditions: None
150 //-------------------
153 if (_isInfiniteTimeout)
155 milliseconds = long.MaxValue;
159 milliseconds = ADP.TimerRemainingMilliseconds(_timerExpire);
160 if (0 > milliseconds)
166 //--------------------
168 Debug.Assert(0<=milliseconds); // This property guarantees no negative return values