Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
CancellationTokenSource.cs
Go to the documentation of this file.
4
5namespace System.Threading;
6
8{
10 {
12
17
18 protected override void Dispose(bool disposing)
19 {
20 if (disposing && !_disposed)
21 {
22 _reg1.Dispose();
23 base.Dispose(disposing);
24 }
25 }
26 }
27
50
52 {
53 internal static readonly Action<object> s_linkedTokenCancelDelegate = delegate(object s)
54 {
55 ((CancellationTokenSource)s).NotifyCancellation(throwOnFirstException: false);
56 };
57
59
61 {
63 for (int i = 0; i < tokens.Length; i++)
64 {
65 if (tokens[i].CanBeCanceled)
66 {
67 _linkingRegistrations[i] = tokens[i].UnsafeRegister(s_linkedTokenCancelDelegate, this);
68 }
69 }
70 }
71
72 protected override void Dispose(bool disposing)
73 {
74 if (!disposing || _disposed)
75 {
76 return;
77 }
79 if (linkingRegistrations != null)
80 {
82 for (int i = 0; i < linkingRegistrations.Length; i++)
83 {
84 linkingRegistrations[i].Dispose();
85 }
86 }
87 base.Dispose(disposing);
88 }
89 }
90
91 internal sealed class Registrations
92 {
94
96
98
99 public long NextAvailableId = 1L;
100
102
103 public volatile int ThreadIDExecutingCallbacks = -1;
104
105 private int _lock;
106
111
112 [MethodImpl(MethodImplOptions.AggressiveInlining)]
114 {
115 node.Id = 0L;
116 node.Callback = null;
117 node.CallbackState = null;
118 node.ExecutionContext = null;
119 node.SynchronizationContext = null;
120 node.Prev = null;
121 node.Next = FreeNodeList;
123 }
124
125 public bool Unregister(long id, CallbackNode node)
126 {
127 if (id == 0L)
128 {
129 return false;
130 }
131 EnterLock();
132 try
133 {
134 if (node.Id != id)
135 {
136 return false;
137 }
138 if (Callbacks == node)
139 {
140 Callbacks = node.Next;
141 }
142 else
143 {
144 node.Prev.Next = node.Next;
145 }
146 if (node.Next != null)
147 {
148 node.Next.Prev = node.Prev;
149 }
150 Recycle(node);
151 return true;
152 }
153 finally
154 {
155 ExitLock();
156 }
157 }
158
159 public void UnregisterAll()
160 {
161 EnterLock();
162 try
163 {
165 Callbacks = null;
166 while (callbackNode != null)
167 {
168 CallbackNode next = callbackNode.Next;
170 callbackNode = next;
171 }
172 }
173 finally
174 {
175 ExitLock();
176 }
177 }
178
179 public void WaitForCallbackToComplete(long id)
180 {
181 SpinWait spinWait = default(SpinWait);
182 while (Volatile.Read(ref ExecutingCallbackId) == id)
183 {
184 spinWait.SpinOnce();
185 }
186 }
187
189 {
191 {
192 return default(ValueTask);
193 }
194 return new ValueTask(Task.Factory.StartNew((Func<object?, Task>)async delegate(object s)
195 {
197 while (Volatile.Read(ref state.Item1.ExecutingCallbackId) == state.Item2)
198 {
199 await Task.Yield();
200 }
202 }
203
204 public void EnterLock()
205 {
206 ref int @lock = ref _lock;
207 if (Interlocked.Exchange(ref @lock, 1) != 0)
208 {
210 }
211 [MethodImpl(MethodImplOptions.NoInlining)]
212 static void Contention(ref int value)
213 {
214 SpinWait spinWait = default(SpinWait);
215 do
216 {
217 spinWait.SpinOnce();
218 }
219 while (Interlocked.Exchange(ref value, 1) == 1);
220 }
221 }
222
223 public void ExitLock()
224 {
226 }
227 }
228
229 internal sealed class CallbackNode
230 {
232
234
236
237 public long Id;
238
240
241 public object CallbackState;
242
244
246
251
252 public void ExecuteCallback()
253 {
255 if (executionContext == null)
256 {
258 return;
259 }
261 {
263 Invoke(callbackNode.Callback, callbackNode.CallbackState, callbackNode.Registrations.Source);
264 }, this);
265 }
266 }
267
269 {
270 _state = 2
271 };
272
274
275 private static readonly TimerCallback s_timerCallback = TimerCallback;
276
277 private volatile int _state;
278
279 private bool _disposed;
280
281 private volatile TimerQueueTimer _timer;
282
284
286
287 public bool IsCancellationRequested => _state != 0;
288
289 internal bool IsCancellationCompleted => _state == 2;
290
291 public CancellationToken Token
292 {
293 get
294 {
296 return new CancellationToken(this);
297 }
298 }
299
301 {
302 get
303 {
305 if (_kernelEvent != null)
306 {
307 return _kernelEvent;
308 }
309 ManualResetEvent manualResetEvent = new ManualResetEvent(initialState: false);
311 {
312 manualResetEvent.Dispose();
313 }
315 {
316 _kernelEvent.Set();
317 }
318 return _kernelEvent;
319 }
320 }
321
322 private static void TimerCallback(object state)
323 {
324 ((CancellationTokenSource)state).NotifyCancellation(throwOnFirstException: false);
325 }
326
328 {
329 }
330
332 {
333 long num = (long)delay.TotalMilliseconds;
334 if (num < -1 || num > 4294967294u)
335 {
337 }
338 InitializeWithTimer((uint)num);
339 }
340
349
351 {
352 if (millisecondsDelay == 0)
353 {
354 _state = 2;
355 }
356 else
357 {
359 }
360 }
361
362 public void Cancel()
363 {
365 }
366
372
374 {
375 long num = (long)delay.TotalMilliseconds;
376 if (num < -1 || num > 4294967294u)
377 {
379 }
380 CancelAfter((uint)num);
381 }
382
384 {
385 if (millisecondsDelay < -1)
386 {
388 }
390 }
391
393 {
396 {
397 return;
398 }
400 if (timerQueueTimer == null)
401 {
402 timerQueueTimer = new TimerQueueTimer(s_timerCallback, this, uint.MaxValue, uint.MaxValue, flowExecutionContext: false);
404 if (timerQueueTimer2 != null)
405 {
406 timerQueueTimer.Close();
408 }
409 }
410 try
411 {
412 timerQueueTimer.Change(millisecondsDelay, uint.MaxValue);
413 }
415 {
416 }
417 }
418
419 public bool TryReset()
420 {
422 if (_state == 0)
423 {
424 bool flag = false;
425 try
426 {
428 flag = timer == null || (timer.Change(uint.MaxValue, uint.MaxValue) && !timer._everQueued);
429 }
431 {
432 }
433 if (flag)
434 {
435 Volatile.Read(ref _registrations)?.UnregisterAll();
436 return true;
437 }
438 }
439 return false;
440 }
441
442 public void Dispose()
443 {
444 Dispose(disposing: true);
445 GC.SuppressFinalize(this);
446 }
447
448 protected virtual void Dispose(bool disposing)
449 {
450 if (!disposing || _disposed)
451 {
452 return;
453 }
455 if (timer != null)
456 {
457 _timer = null;
458 timer.Close();
459 }
460 _registrations = null;
461 if (_kernelEvent != null)
462 {
464 if (manualResetEvent != null && _state != 1)
465 {
466 manualResetEvent.Dispose();
467 }
468 }
469 _disposed = true;
470 }
471
472 private void ThrowIfDisposed()
473 {
474 if (_disposed)
475 {
476 ThrowHelper.ThrowObjectDisposedException(ExceptionResource.CancellationTokenSource_Disposed);
477 }
478 }
479
481 {
483 {
484 if (_disposed)
485 {
486 return default(CancellationTokenRegistration);
487 }
489 if (registrations == null)
490 {
491 registrations = new Registrations(this);
493 }
495 long id = 0L;
496 if (registrations.FreeNodeList != null)
497 {
498 registrations.EnterLock();
499 try
500 {
501 callbackNode = registrations.FreeNodeList;
502 if (callbackNode != null)
503 {
504 registrations.FreeNodeList = callbackNode.Next;
505 id = (callbackNode.Id = registrations.NextAvailableId++);
506 callbackNode.Callback = callback;
507 callbackNode.CallbackState = stateForCallback;
508 callbackNode.ExecutionContext = executionContext;
509 callbackNode.SynchronizationContext = syncContext;
510 callbackNode.Next = registrations.Callbacks;
511 registrations.Callbacks = callbackNode;
512 if (callbackNode.Next != null)
513 {
514 callbackNode.Next.Prev = callbackNode;
515 }
516 }
517 }
518 finally
519 {
520 registrations.ExitLock();
521 }
522 }
523 if (callbackNode == null)
524 {
526 callbackNode.Callback = callback;
527 callbackNode.CallbackState = stateForCallback;
528 callbackNode.ExecutionContext = executionContext;
529 callbackNode.SynchronizationContext = syncContext;
530 registrations.EnterLock();
531 try
532 {
533 id = (callbackNode.Id = registrations.NextAvailableId++);
534 callbackNode.Next = registrations.Callbacks;
535 if (callbackNode.Next != null)
536 {
537 callbackNode.Next.Prev = callbackNode;
538 }
539 registrations.Callbacks = callbackNode;
540 }
541 finally
542 {
543 registrations.ExitLock();
544 }
545 }
546 if (!IsCancellationRequested || !registrations.Unregister(id, callbackNode))
547 {
549 }
550 }
551 Invoke(callback, stateForCallback, this);
552 return default(CancellationTokenRegistration);
553 }
554
556 {
558 {
560 if (timer != null)
561 {
562 _timer = null;
563 timer.Close();
564 }
565 _kernelEvent?.Set();
567 }
568 }
569
571 {
573 if (registrations == null)
574 {
576 return;
577 }
578 registrations.ThreadIDExecutingCallbacks = Environment.CurrentManagedThreadId;
579 List<Exception> list = null;
580 try
581 {
582 while (true)
583 {
584 registrations.EnterLock();
586 try
587 {
588 callbacks = registrations.Callbacks;
589 if (callbacks == null)
590 {
591 break;
592 }
593 if (callbacks.Next != null)
594 {
595 callbacks.Next.Prev = null;
596 }
597 registrations.Callbacks = callbacks.Next;
598 registrations.ExecutingCallbackId = callbacks.Id;
599 callbacks.Id = 0L;
600 goto IL_0080;
601 }
602 finally
603 {
604 registrations.ExitLock();
605 }
606 IL_0080:
607 try
608 {
609 if (callbacks.SynchronizationContext != null)
610 {
611 callbacks.SynchronizationContext.Send(delegate(object s)
612 {
614 callbackNode.Registrations.ThreadIDExecutingCallbacks = Environment.CurrentManagedThreadId;
615 callbackNode.ExecuteCallback();
616 }, callbacks);
617 registrations.ThreadIDExecutingCallbacks = Environment.CurrentManagedThreadId;
618 }
619 else
620 {
621 callbacks.ExecuteCallback();
622 }
623 }
625 {
626 (list ?? (list = new List<Exception>())).Add(item);
627 }
628 }
629 }
630 finally
631 {
632 _state = 2;
633 Interlocked.Exchange(ref registrations.ExecutingCallbackId, 0L);
634 }
635 if (list == null)
636 {
637 return;
638 }
639 throw new AggregateException(list);
640 }
641
643 {
644 if (token1.CanBeCanceled)
645 {
646 if (!token2.CanBeCanceled)
647 {
649 }
651 }
653 }
654
656 {
657 if (!token.CanBeCanceled)
658 {
659 return new CancellationTokenSource();
660 }
661 return new Linked1CancellationTokenSource(token);
662 }
663
665 {
666 if (tokens == null)
667 {
668 throw new ArgumentNullException("tokens");
669 }
670 return tokens.Length switch
671 {
676 };
677 }
678
679 private static void Invoke(Delegate d, object state, CancellationTokenSource source)
680 {
682 {
683 action(state);
684 }
685 else
686 {
688 }
689 }
690}
void Add(TKey key, TValue value)
static int CurrentManagedThreadId
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
static string CancellationToken_CreateLinkedToken_TokensIsEmpty
Definition SR.cs:1176
Definition SR.cs:7
Linked2CancellationTokenSource(CancellationToken token1, CancellationToken token2)
static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token)
static readonly CancellationTokenSource s_canceledSource
void NotifyCancellation(bool throwOnFirstException)
static void Invoke(Delegate d, object state, CancellationTokenSource source)
static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token1, CancellationToken token2)
CancellationTokenRegistration Register(Delegate callback, object stateForCallback, SynchronizationContext syncContext, ExecutionContext executionContext)
void ExecuteCallbackHandlers(bool throwOnFirstException)
static readonly CancellationTokenSource s_neverCanceledSource
static CancellationTokenSource CreateLinkedTokenSource(params CancellationToken[] tokens)
static void RunInternal(ExecutionContext executionContext, ContextCallback callback, object state)
static int CompareExchange(ref int location1, int value, int comparand)
static int Exchange(ref int location1, int value)
static new TaskFactory< TResult > Factory
Definition Task.cs:56
static bool Read(ref bool location)
Definition Volatile.cs:67
static void Write(ref bool location, bool value)
Definition Volatile.cs:74
static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
static void ThrowObjectDisposedException(ExceptionResource resource)