Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data / System / Data / ProviderBase / TimeoutTimer.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="TimeoutTimer.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 //  Class used to manage timeouts in complex system operations.
7 //
8 // <owner current="true" primary="true">Microsoft</owner>
9 // <owner current="true" primary="false">Microsoft</owner>
10 //------------------------------------------------------------------------------
11
12 namespace System.Data.ProviderBase
13 {
14     using System;
15     using System.Data.Common;
16     using System.Diagnostics;
17
18 // Purpose:
19 //   Manages determining and tracking timeouts
20 //
21 // Intended use:
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
27 {
28     //-------------------
29     // Fields
30     //-------------------
31     private long _timerExpire;
32     private bool _isInfiniteTimeout;
33
34     //-------------------
35     // Timeout-setting methods
36     //-------------------
37
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)
41     {
42         //--------------------
43         // Preconditions: None (seconds must conform to SetTimeoutSeconds requirements)
44
45         //--------------------
46         // Method body
47         var timeout = new TimeoutTimer();
48         timeout.SetTimeoutSeconds(seconds);
49
50         //---------------------
51         // Postconditions
52         Debug.Assert(timeout != null); // Need a valid timeouttimer if no error
53
54         return timeout;
55     }
56
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)
60     {
61         //--------------------
62         // Preconditions
63         Debug.Assert(0 <= milliseconds);
64
65         //--------------------
66         // Method body
67         var timeout = new TimeoutTimer();
68         timeout._timerExpire = checked(ADP.TimerCurrent() + (milliseconds * TimeSpan.TicksPerMillisecond));
69         timeout._isInfiniteTimeout = false;
70
71         //---------------------
72         // Postconditions
73         Debug.Assert(timeout != null); // Need a valid timeouttimer if no error
74
75         return timeout;
76     }
77
78     //-------------------
79     // Methods for changing timeout
80     //-------------------
81
82     internal void SetTimeoutSeconds(int seconds)
83     {
84         //--------------------
85         // Preconditions
86         Debug.Assert(0 <= seconds || InfiniteTimeout == seconds);  // no need to support negative seconds at present
87
88         //--------------------
89         // Method body
90         if (InfiniteTimeout == seconds)
91         {
92             _isInfiniteTimeout = true;
93         }
94         else
95         {
96             // Stash current time + timeout
97             _timerExpire = checked(ADP.TimerCurrent() + ADP.TimerFromSeconds(seconds));
98             _isInfiniteTimeout = false;
99         }
100
101         //---------------------
102         // Postconditions:None
103     }
104
105     //-------------------
106     // Timeout info properties
107     //-------------------
108
109     // Indicator for infinite timeout when starting a timer
110     internal static readonly long InfiniteTimeout = 0;
111
112     // Is this timer in an expired state?
113     internal bool IsExpired 
114     {
115         get 
116         {
117             return !IsInfinite && ADP.TimerHasExpired(_timerExpire);
118         }
119     }
120
121     // is this an infinite-timeout timer?
122     internal bool IsInfinite
123     {
124         get
125         {
126             return _isInfiniteTimeout;
127         }
128     }
129
130     // Special accessor for TimerExpire for use when thunking to legacy timeout methods.
131     internal long LegacyTimerExpire
132     {
133         get
134         {
135             return (_isInfiniteTimeout) ? Int64.MaxValue : _timerExpire;
136         }
137     }
138
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
144     {
145         get 
146         {
147             //-------------------
148             // Preconditions: None
149
150             //-------------------
151             // Method Body
152             long milliseconds;
153             if (_isInfiniteTimeout)
154             {
155                 milliseconds = long.MaxValue;
156             }
157             else
158             {
159                 milliseconds = ADP.TimerRemainingMilliseconds(_timerExpire);
160                 if (0 > milliseconds)
161                 {
162                     milliseconds = 0;
163                 }
164             }
165
166             //--------------------
167             // Postconditions
168             Debug.Assert(0<=milliseconds); // This property guarantees no negative return values
169
170             return milliseconds;
171         }
172     }
173
174 }
175
176 }
177