Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
SemaphoreSlim.cs
Go to the documentation of this file.
5
6namespace System.Threading;
7
8[DebuggerDisplay("Current Count = {m_currentCount}")]
10{
11 private sealed class TaskNode : Task<bool>
12 {
13 internal TaskNode Prev;
14
15 internal TaskNode Next;
16
17 internal TaskNode()
19 {
20 }
21 }
22
24 {
25 private readonly Task<T> _task;
26
28
33
35 {
36 return this;
37 }
38
39 public void GetResult()
40 {
41 }
42
43 public void UnsafeOnCompleted(Action continuation)
44 {
45 _task.ConfigureAwait(continueOnCapturedContext: false).GetAwaiter().UnsafeOnCompleted(continuation);
46 }
47
48 public void OnCompleted(Action continuation)
49 {
50 _task.ConfigureAwait(continueOnCapturedContext: false).GetAwaiter().OnCompleted(continuation);
51 }
52 }
53
54 private volatile int m_currentCount;
55
56 private readonly int m_maxCount;
57
58 private int m_waitCount;
59
61
63
65
67
69
71
73
75 {
76 get
77 {
79 if (m_waitHandle != null)
80 {
81 return m_waitHandle;
82 }
84 {
85 if (m_waitHandle == null)
86 {
88 }
89 }
90 return m_waitHandle;
91 }
92 }
93
94 public SemaphoreSlim(int initialCount)
95 : this(initialCount, int.MaxValue)
96 {
97 }
98
99 public SemaphoreSlim(int initialCount, int maxCount)
100 {
101 if (initialCount < 0 || initialCount > maxCount)
102 {
103 throw new ArgumentOutOfRangeException("initialCount", initialCount, SR.SemaphoreSlim_ctor_InitialCountWrong);
104 }
105 if (maxCount <= 0)
106 {
107 throw new ArgumentOutOfRangeException("maxCount", maxCount, SR.SemaphoreSlim_ctor_MaxCountWrong);
108 }
109 m_maxCount = maxCount;
110 m_currentCount = initialCount;
112 }
113
114 [UnsupportedOSPlatform("browser")]
115 public void Wait()
116 {
118 }
119
120 [UnsupportedOSPlatform("browser")]
125
126 [UnsupportedOSPlatform("browser")]
127 public bool Wait(TimeSpan timeout)
128 {
129 long num = (long)timeout.TotalMilliseconds;
130 if (num < -1 || num > int.MaxValue)
131 {
133 }
134 return Wait((int)timeout.TotalMilliseconds, CancellationToken.None);
135 }
136
137 [UnsupportedOSPlatform("browser")]
139 {
140 long num = (long)timeout.TotalMilliseconds;
141 if (num < -1 || num > int.MaxValue)
142 {
144 }
145 return Wait((int)timeout.TotalMilliseconds, cancellationToken);
146 }
147
148 [UnsupportedOSPlatform("browser")]
149 public bool Wait(int millisecondsTimeout)
150 {
152 }
153
154 [UnsupportedOSPlatform("browser")]
156 {
157 CheckDispose();
158 if (millisecondsTimeout < -1)
159 {
161 }
162 cancellationToken.ThrowIfCancellationRequested();
163 if (millisecondsTimeout == 0 && m_currentCount == 0)
164 {
165 return false;
166 }
167 uint startTime = 0u;
169 {
170 startTime = TimeoutHelper.GetTime();
171 }
172 bool flag = false;
173 Task<bool> task = null;
174 bool lockTaken = false;
175 CancellationTokenRegistration cancellationTokenRegistration = cancellationToken.UnsafeRegister(s_cancellationTokenCanceledEventHandler, this);
176 try
177 {
178 if (m_currentCount == 0)
179 {
180 int num = SpinWait.SpinCountforSpinBeforeWait * 4;
181 SpinWait spinWait = default(SpinWait);
182 while (spinWait.Count < num)
183 {
184 spinWait.SpinOnce(-1);
185 if (m_currentCount != 0)
186 {
187 break;
188 }
189 }
190 }
191 Monitor.Enter(m_lockObjAndDisposed, ref lockTaken);
192 m_waitCount++;
193 if (m_asyncHead != null)
194 {
196 }
197 else
198 {
200 if (m_currentCount == 0)
201 {
202 if (millisecondsTimeout == 0)
203 {
204 return false;
205 }
206 try
207 {
209 }
211 {
212 ex = ex2;
213 }
214 }
215 if (m_currentCount > 0)
216 {
217 flag = true;
219 }
220 else if (ex != null)
221 {
222 throw ex;
223 }
224 if (m_waitHandle != null && m_currentCount == 0)
225 {
227 }
228 }
229 }
230 finally
231 {
232 if (lockTaken)
233 {
234 m_waitCount--;
236 }
237 cancellationTokenRegistration.Dispose();
238 }
239 return task?.GetAwaiter().GetResult() ?? flag;
240 }
241
242 [UnsupportedOSPlatform("browser")]
244 {
245 int num = -1;
246 while (m_currentCount == 0)
247 {
248 cancellationToken.ThrowIfCancellationRequested();
249 if (millisecondsTimeout != -1)
250 {
252 if (num <= 0)
253 {
254 return false;
255 }
256 }
257 bool flag = Monitor.Wait(m_lockObjAndDisposed, num);
259 {
261 }
262 if (!flag)
263 {
264 return false;
265 }
266 }
267 return true;
268 }
269
271 {
272 return WaitAsync(-1, default(CancellationToken));
273 }
274
279
284
286 {
287 return WaitAsync(timeout, default(CancellationToken));
288 }
289
291 {
292 long num = (long)timeout.TotalMilliseconds;
293 if (num < -1 || num > int.MaxValue)
294 {
296 }
297 return WaitAsync((int)timeout.TotalMilliseconds, cancellationToken);
298 }
299
301 {
302 CheckDispose();
303 if (millisecondsTimeout < -1)
304 {
306 }
307 if (cancellationToken.IsCancellationRequested)
308 {
309 return Task.FromCanceled<bool>(cancellationToken);
310 }
312 {
313 if (m_currentCount > 0)
314 {
316 if (m_waitHandle != null && m_currentCount == 0)
317 {
319 }
320 return Task.FromResult(result: true);
321 }
322 if (millisecondsTimeout == 0)
323 {
324 return Task.FromResult(result: false);
325 }
327 return (millisecondsTimeout == -1 && !cancellationToken.CanBeCanceled) ? taskNode : WaitUntilCountOrTimeoutAsync(taskNode, millisecondsTimeout, cancellationToken);
328 }
329 }
330
332 {
333 TaskNode taskNode = new TaskNode();
334 if (m_asyncHead == null)
335 {
336 m_asyncHead = taskNode;
337 m_asyncTail = taskNode;
338 }
339 else
340 {
341 m_asyncTail.Next = taskNode;
342 taskNode.Prev = m_asyncTail;
343 m_asyncTail = taskNode;
344 }
345 return taskNode;
346 }
347
349 {
350 bool result = m_asyncHead == task || task.Prev != null;
351 if (task.Next != null)
352 {
353 task.Next.Prev = task.Prev;
354 }
355 if (task.Prev != null)
356 {
357 task.Prev.Next = task.Next;
358 }
359 if (m_asyncHead == task)
360 {
362 }
363 if (m_asyncTail == task)
364 {
366 }
367 task.Next = (task.Prev = null);
368 return result;
369 }
370
372 {
374 if (cancellationToken.IsCancellationRequested)
375 {
377 }
378 if (asyncWaiter.IsCompleted)
379 {
380 return true;
381 }
383 {
384 if (RemoveAsyncWaiter(asyncWaiter))
385 {
386 cancellationToken.ThrowIfCancellationRequested();
387 return false;
388 }
389 }
390 return await asyncWaiter.ConfigureAwait(continueOnCapturedContext: false);
391 }
392
393 public int Release()
394 {
395 return Release(1);
396 }
397
398 public int Release(int releaseCount)
399 {
400 CheckDispose();
401 if (releaseCount < 1)
402 {
403 throw new ArgumentOutOfRangeException("releaseCount", releaseCount, SR.SemaphoreSlim_Release_CountWrong);
404 }
405 int num;
407 {
408 int currentCount = m_currentCount;
409 num = currentCount;
410 if (m_maxCount - currentCount < releaseCount)
411 {
412 throw new SemaphoreFullException();
413 }
414 currentCount += releaseCount;
415 int waitCount = m_waitCount;
416 int num2 = Math.Min(currentCount, waitCount) - m_countOfWaitersPulsedToWake;
417 if (num2 > 0)
418 {
419 if (num2 > releaseCount)
420 {
421 num2 = releaseCount;
422 }
424 for (int i = 0; i < num2; i++)
425 {
427 }
428 }
429 if (m_asyncHead != null)
430 {
431 int num3 = currentCount - waitCount;
432 while (num3 > 0 && m_asyncHead != null)
433 {
434 currentCount--;
435 num3--;
436 TaskNode asyncHead = m_asyncHead;
437 RemoveAsyncWaiter(asyncHead);
438 asyncHead.TrySetResult(result: true);
439 }
440 }
441 m_currentCount = currentCount;
442 if (m_waitHandle != null && num == 0 && currentCount > 0)
443 {
445 }
446 }
447 return num;
448 }
449
450 public void Dispose()
451 {
452 Dispose(disposing: true);
453 GC.SuppressFinalize(this);
454 }
455
456 protected virtual void Dispose(bool disposing)
457 {
458 if (disposing)
459 {
460 WaitHandle waitHandle = m_waitHandle;
461 if (waitHandle != null)
462 {
463 waitHandle.Dispose();
464 m_waitHandle = null;
465 }
466 m_lockObjAndDisposed.Value = true;
467 m_asyncHead = null;
468 m_asyncTail = null;
469 }
470 }
471
472 private static void CancellationTokenCanceledEventHandler(object obj)
473 {
474 SemaphoreSlim semaphoreSlim = (SemaphoreSlim)obj;
475 lock (semaphoreSlim.m_lockObjAndDisposed)
476 {
478 }
479 }
480
481 private void CheckDispose()
482 {
484 {
486 }
487 }
488}
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static string SemaphoreSlim_Disposed
Definition SR.cs:1864
static string SemaphoreSlim_ctor_MaxCountWrong
Definition SR.cs:1862
static string SemaphoreSlim_ctor_InitialCountWrong
Definition SR.cs:1860
static string SemaphoreSlim_Wait_TimeoutWrong
Definition SR.cs:1868
static string SemaphoreSlim_Release_CountWrong
Definition SR.cs:1866
Definition SR.cs:7
static void Exit(object obj)
static void PulseAll(object obj)
Definition Monitor.cs:115
static bool Wait(object obj, int millisecondsTimeout)
Definition Monitor.cs:87
static void Enter(object obj)
static void Pulse(object obj)
Definition Monitor.cs:103
SemaphoreSlim(int initialCount)
Task< bool > WaitAsync(TimeSpan timeout)
static void CancellationTokenCanceledEventHandler(object obj)
void Wait(CancellationToken cancellationToken)
bool RemoveAsyncWaiter(TaskNode task)
Task< bool > WaitAsync(TimeSpan timeout, CancellationToken cancellationToken)
async Task< bool > WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, int millisecondsTimeout, CancellationToken cancellationToken)
int Release(int releaseCount)
bool Wait(int millisecondsTimeout)
bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
bool WaitUntilCountOrTimeout(int millisecondsTimeout, uint startTime, CancellationToken cancellationToken)
Task< bool > WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken)
bool Wait(TimeSpan timeout, CancellationToken cancellationToken)
static readonly Action< object > s_cancellationTokenCanceledEventHandler
readonly StrongBox< bool > m_lockObjAndDisposed
Task WaitAsync(CancellationToken cancellationToken)
bool Wait(TimeSpan timeout)
Task< bool > WaitAsync(int millisecondsTimeout)
volatile ManualResetEvent m_waitHandle
virtual void Dispose(bool disposing)
SemaphoreSlim(int initialCount, int maxCount)
bool TrySetResult(TResult result)
Definition Task.cs:162
new ConfiguredTaskAwaitable< TResult > ConfigureAwait(bool continueOnCapturedContext)
Definition Task.cs:226
new Task< TResult > WaitAsync(CancellationToken cancellationToken)
Definition Task.cs:231
static Task FromCanceled(CancellationToken cancellationToken)
Definition Task.cs:3363
static int UpdateTimeOut(uint startTime, int originalWaitMillisecondsTimeout)
virtual void Dispose(bool explicitDisposing)
static TimeSpan FromMilliseconds(double value)
Definition TimeSpan.cs:228