Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
RegisteredWaitHandle.cs
Go to the documentation of this file.
5
6namespace System.Threading;
7
8[UnsupportedOSPlatform("browser")]
10{
12
13 private bool _releaseHandle;
14
16
17 private static readonly LowLevelLock s_callbackLock = new LowLevelLock();
18
20
22
23 private bool _unregisterCalled;
24
25 private bool _unregistered;
26
28
30
31 internal _ThreadPoolWaitOrTimerCallback Callback { get; }
32
33 internal SafeWaitHandle Handle { get; }
34
35 internal int TimeoutTimeMs { get; private set; }
36
37 internal int TimeoutDurationMs { get; }
38
39 internal bool IsInfiniteTimeout => TimeoutDurationMs == -1;
40
41 internal bool Repeating { get; }
42
44
46
47 private static IntPtr InvalidHandleValue => new IntPtr(-1);
48
50
52
53 private static bool IsValidHandle(IntPtr handle)
54 {
56 {
57 return handle != IntPtr.Zero;
58 }
59 return false;
60 }
61
62 internal void SetNativeRegisteredWaitHandle(IntPtr nativeRegisteredWaitHandle)
63 {
64 _nativeRegisteredWaitHandle = nativeRegisteredWaitHandle;
65 }
66
67 internal void OnBeforeRegister()
68 {
70 {
71 GC.SuppressFinalize(this);
72 }
73 else
74 {
76 }
77 }
78
79 public bool Unregister(WaitHandle waitObject)
80 {
82 {
83 return UnregisterPortable(waitObject);
84 }
85 s_callbackLock.Acquire();
86 try
87 {
89 {
90 return false;
91 }
94 {
96 _releaseHandle = false;
97 }
98 }
99 finally
100 {
101 s_callbackLock.Release();
102 }
103 GC.SuppressFinalize(this);
104 return true;
105 }
106
108 {
110 {
111 return;
112 }
113 s_callbackLock.Acquire();
114 try
115 {
117 {
120 if (_releaseHandle)
121 {
123 _releaseHandle = false;
124 }
125 }
126 }
127 finally
128 {
129 s_callbackLock.Release();
130 }
131 }
132
133 [MethodImpl(MethodImplOptions.InternalCall)]
134 private static extern void WaitHandleCleanupNative(IntPtr handle);
135
136 [MethodImpl(MethodImplOptions.InternalCall)]
137 private static extern bool UnregisterWaitNative(IntPtr handle, SafeHandle waitObject);
138
139 internal RegisteredWaitHandle(WaitHandle waitHandle, _ThreadPoolWaitOrTimerCallback callbackHelper, int millisecondsTimeout, bool repeating)
140 {
141 Handle = waitHandle.SafeWaitHandle;
142 Callback = callbackHelper;
144 Repeating = repeating;
146 {
148 }
149 }
150
151 private static AutoResetEvent RentEvent()
152 {
153 return Interlocked.Exchange(ref s_cachedEvent, null) ?? new AutoResetEvent(initialState: false);
154 }
155
156 private static void ReturnEvent(AutoResetEvent resetEvent)
157 {
158 if (Interlocked.CompareExchange(ref s_cachedEvent, resetEvent, null) != null)
159 {
160 resetEvent.Dispose();
161 }
162 }
163
164 internal void RestartTimeout()
165 {
166 TimeoutTimeMs = Environment.TickCount + TimeoutDurationMs;
167 }
168
169 private bool UnregisterPortable(WaitHandle waitObject)
170 {
171 s_callbackLock.Acquire();
172 bool success = false;
173 try
174 {
176 {
177 return false;
178 }
182 if (_unregistered)
183 {
185 return true;
186 }
187 if (IsBlocking)
188 {
190 }
191 else
192 {
194 }
195 }
196 catch (Exception)
197 {
198 if (_removed != null)
199 {
201 _removed = null;
202 }
203 else if (_callbacksComplete != null)
204 {
206 _callbacksComplete = null;
207 }
209 if (success)
210 {
212 }
214 throw;
215 }
216 finally
217 {
218 _unregisterCalled = true;
219 s_callbackLock.Release();
220 }
221 WaitThread.UnregisterWait(this);
222 return true;
223 }
224
225 private void SignalUserWaitHandle()
226 {
227 SafeWaitHandle userUnregisterWaitHandle = UserUnregisterWaitHandle;
228 IntPtr userUnregisterWaitHandleValue = UserUnregisterWaitHandleValue;
229 try
230 {
231 if (userUnregisterWaitHandleValue != IntPtr.Zero && userUnregisterWaitHandleValue != InvalidHandleValue)
232 {
233 EventWaitHandle.Set(userUnregisterWaitHandle);
234 }
235 }
236 finally
237 {
238 userUnregisterWaitHandle?.DangerousRelease();
240 _unregistered = true;
241 }
242 }
243
244 internal void PerformCallback(bool timedOut)
245 {
248 }
249
250 internal void RequestCallback()
251 {
252 s_callbackLock.Acquire();
253 try
254 {
256 }
257 finally
258 {
259 s_callbackLock.Release();
260 }
261 }
262
263 internal void OnRemoveWait()
264 {
265 s_callbackLock.Acquire();
266 try
267 {
268 _removed?.Set();
269 if (_numRequestedCallbacks == 0)
270 {
272 }
273 else
274 {
276 }
277 }
278 finally
279 {
280 s_callbackLock.Release();
281 }
282 }
283
285 {
286 s_callbackLock.Acquire();
287 try
288 {
291 {
293 }
294 }
295 finally
296 {
297 s_callbackLock.Release();
298 }
299 }
300
307
308 internal void WaitForRemoval()
309 {
312 _removed = null;
313 }
314}
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
void DangerousAddRef(ref bool success)
Definition SafeHandle.cs:76
static int CompareExchange(ref int location1, int value, int comparand)
static int Exchange(ref int location1, int value)
PortableThreadPool.? WaitThread WaitThread
void SetNativeRegisteredWaitHandle(IntPtr nativeRegisteredWaitHandle)
RegisteredWaitHandle(WaitHandle waitHandle, _ThreadPoolWaitOrTimerCallback callbackHelper, int millisecondsTimeout, bool repeating)
bool UnregisterPortable(WaitHandle waitObject)
static bool UnregisterWaitNative(IntPtr handle, SafeHandle waitObject)
static void ReturnEvent(AutoResetEvent resetEvent)
static readonly LowLevelLock s_callbackLock
static void WaitHandleCleanupNative(IntPtr handle)
static readonly bool UsePortableThreadPool
Definition ThreadPool.cs:12
virtual void Dispose(bool explicitDisposing)
SafeWaitHandle SafeWaitHandle
Definition WaitHandle.cs:54
virtual bool WaitOne(int millisecondsTimeout)
static void PerformWaitOrTimerCallback(_ThreadPoolWaitOrTimerCallback helper, bool timedOut)
static readonly IntPtr Zero
Definition IntPtr.cs:18