/// <summary> /// Registers a callback object. If cancellation has already occurred, the /// callback will have been run by the time this method returns. /// </summary> internal CancellationTokenRegistration InternalRegister( Action <object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext) { ThrowIfDisposed(); // the CancellationToken has already checked that the token is cancelable before calling this method. Contract.Assert(CanBeCanceled, "Cannot register for uncancelable token src"); // if not canceled, register the event handlers // if canceled already, run the callback synchronously // Apart from the semantics of late-enlistment, this also ensures that during ExecuteCallbackHandlers() there // will be no mutation of the _registeredCallbacks list if (!IsCancellationRequested) { int myIndex = Thread.CurrentThread.ManagedThreadId % s_nLists; CancellationCallbackInfo callbackInfo = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this); //allocate the callback list array if (m_registeredCallbacksLists == null) { SparselyPopulatedArray <CancellationCallbackInfo>[] list = new SparselyPopulatedArray <CancellationCallbackInfo> [s_nLists]; Interlocked.CompareExchange(ref m_registeredCallbacksLists, list, null); } //allocate the actual lists on-demand to save mem in low-use situations, and to avoid false-sharing. if (m_registeredCallbacksLists[myIndex] == null) { SparselyPopulatedArray <CancellationCallbackInfo> callBackArray = new SparselyPopulatedArray <CancellationCallbackInfo>(4); Interlocked.CompareExchange(ref (m_registeredCallbacksLists[myIndex]), callBackArray, null); } // Now add the registration to the list. SparselyPopulatedArray <CancellationCallbackInfo> callbacks = m_registeredCallbacksLists[myIndex]; SparselyPopulatedArrayAddInfo <CancellationCallbackInfo> addInfo = callbacks.Add(callbackInfo); CancellationTokenRegistration registration = new CancellationTokenRegistration(this, callbackInfo, addInfo); if (!IsCancellationRequested) { return(registration); } //If a cancellation has since come in, we will try to undo the registration and run the callback directly here. bool deregisterOccurred = registration.TryDeregister(); if (!deregisterOccurred) { // the callback execution process must have snagged the callback for execution, so // 1. wait for the callback to complete, then // 2. return a dummy registration. WaitForCallbackToComplete(callbackInfo); return(new CancellationTokenRegistration()); } } // If cancellation already occurred, we run the callback on this thread and return an empty registration. callback(stateForCallback); return(new CancellationTokenRegistration()); }
internal CancellationTokenRegistration InternalRegister(Action <object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext) { this.ThrowIfDisposed(); if (!this.IsCancellationRequested) { int index = Thread.CurrentThread.ManagedThreadId % s_nLists; CancellationCallbackInfo element = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this); if (this.m_registeredCallbacksLists == null) { SparselyPopulatedArray <CancellationCallbackInfo>[] arrayArray = new SparselyPopulatedArray <CancellationCallbackInfo> [s_nLists]; Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo>[]>(ref this.m_registeredCallbacksLists, arrayArray, null); } if (this.m_registeredCallbacksLists[index] == null) { SparselyPopulatedArray <CancellationCallbackInfo> array = new SparselyPopulatedArray <CancellationCallbackInfo>(4); Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo> >(ref this.m_registeredCallbacksLists[index], array, null); } SparselyPopulatedArrayAddInfo <CancellationCallbackInfo> registrationInfo = this.m_registeredCallbacksLists[index].Add(element); CancellationTokenRegistration registration = new CancellationTokenRegistration(this, element, registrationInfo); if (!this.IsCancellationRequested) { return(registration); } if (!registration.TryDeregister()) { this.WaitForCallbackToComplete(element); return(new CancellationTokenRegistration()); } } callback(stateForCallback); return(new CancellationTokenRegistration()); }
// Token: 0x06003E40 RID: 15936 RVA: 0x000E71FC File Offset: 0x000E53FC internal CancellationTokenRegistration InternalRegister(Action <object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext) { if (AppContextSwitches.ThrowExceptionIfDisposedCancellationTokenSource) { this.ThrowIfDisposed(); } if (!this.IsCancellationRequested) { if (this.m_disposed && !AppContextSwitches.ThrowExceptionIfDisposedCancellationTokenSource) { return(default(CancellationTokenRegistration)); } int num = Thread.CurrentThread.ManagedThreadId % CancellationTokenSource.s_nLists; CancellationCallbackInfo cancellationCallbackInfo = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this); SparselyPopulatedArray <CancellationCallbackInfo>[] array = this.m_registeredCallbacksLists; if (array == null) { SparselyPopulatedArray <CancellationCallbackInfo>[] array2 = new SparselyPopulatedArray <CancellationCallbackInfo> [CancellationTokenSource.s_nLists]; array = Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo>[]>(ref this.m_registeredCallbacksLists, array2, null); if (array == null) { array = array2; } } SparselyPopulatedArray <CancellationCallbackInfo> sparselyPopulatedArray = Volatile.Read <SparselyPopulatedArray <CancellationCallbackInfo> >(ref array[num]); if (sparselyPopulatedArray == null) { SparselyPopulatedArray <CancellationCallbackInfo> value = new SparselyPopulatedArray <CancellationCallbackInfo>(4); Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo> >(ref array[num], value, null); sparselyPopulatedArray = array[num]; } SparselyPopulatedArrayAddInfo <CancellationCallbackInfo> registrationInfo = sparselyPopulatedArray.Add(cancellationCallbackInfo); CancellationTokenRegistration result = new CancellationTokenRegistration(cancellationCallbackInfo, registrationInfo); if (!this.IsCancellationRequested) { return(result); } if (!result.TryDeregister()) { return(result); } } callback(stateForCallback); return(default(CancellationTokenRegistration)); }
internal CancellationTokenRegistration InternalRegister(Action <object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext) { if (AppContextSwitches.ThrowExceptionIfDisposedCancellationTokenSource) { this.ThrowIfDisposed(); } if (!this.IsCancellationRequested) { if (this.m_disposed && !AppContextSwitches.ThrowExceptionIfDisposedCancellationTokenSource) { return(new CancellationTokenRegistration()); } int index = Thread.CurrentThread.ManagedThreadId % CancellationTokenSource.s_nLists; CancellationCallbackInfo cancellationCallbackInfo = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this); SparselyPopulatedArray <CancellationCallbackInfo>[] sparselyPopulatedArrayArray1 = this.m_registeredCallbacksLists; if (sparselyPopulatedArrayArray1 == null) { SparselyPopulatedArray <CancellationCallbackInfo>[] sparselyPopulatedArrayArray2 = new SparselyPopulatedArray <CancellationCallbackInfo> [CancellationTokenSource.s_nLists]; sparselyPopulatedArrayArray1 = Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo>[]>(ref this.m_registeredCallbacksLists, sparselyPopulatedArrayArray2, (SparselyPopulatedArray <CancellationCallbackInfo>[])null) ?? sparselyPopulatedArrayArray2; } SparselyPopulatedArray <CancellationCallbackInfo> sparselyPopulatedArray1 = Volatile.Read <SparselyPopulatedArray <CancellationCallbackInfo> >(ref sparselyPopulatedArrayArray1[index]); if (sparselyPopulatedArray1 == null) { SparselyPopulatedArray <CancellationCallbackInfo> sparselyPopulatedArray2 = new SparselyPopulatedArray <CancellationCallbackInfo>(4); Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo> >(ref sparselyPopulatedArrayArray1[index], sparselyPopulatedArray2, (SparselyPopulatedArray <CancellationCallbackInfo>)null); sparselyPopulatedArray1 = sparselyPopulatedArrayArray1[index]; } SparselyPopulatedArrayAddInfo <CancellationCallbackInfo> registrationInfo = sparselyPopulatedArray1.Add(cancellationCallbackInfo); CancellationTokenRegistration tokenRegistration = new CancellationTokenRegistration(cancellationCallbackInfo, registrationInfo); if (!this.IsCancellationRequested || !tokenRegistration.TryDeregister()) { return(tokenRegistration); } } callback(stateForCallback); return(new CancellationTokenRegistration()); }
internal CancellationTokenRegistration InternalRegister(Action<object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext) { this.ThrowIfDisposed(); if (!this.IsCancellationRequested) { int index = Thread.CurrentThread.ManagedThreadId % s_nLists; CancellationCallbackInfo element = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this); if (this.m_registeredCallbacksLists == null) { SparselyPopulatedArray<CancellationCallbackInfo>[] arrayArray = new SparselyPopulatedArray<CancellationCallbackInfo>[s_nLists]; Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>[]>(ref this.m_registeredCallbacksLists, arrayArray, null); } if (this.m_registeredCallbacksLists[index] == null) { SparselyPopulatedArray<CancellationCallbackInfo> array = new SparselyPopulatedArray<CancellationCallbackInfo>(4); Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>>(ref this.m_registeredCallbacksLists[index], array, null); } SparselyPopulatedArrayAddInfo<CancellationCallbackInfo> registrationInfo = this.m_registeredCallbacksLists[index].Add(element); CancellationTokenRegistration registration = new CancellationTokenRegistration(this, element, registrationInfo); if (!this.IsCancellationRequested) { return registration; } if (!registration.TryDeregister()) { this.WaitForCallbackToComplete(element); return new CancellationTokenRegistration(); } } callback(stateForCallback); return new CancellationTokenRegistration(); }
internal CancellationTokenRegistration InternalRegister(Action<object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext) { this.ThrowIfDisposed(); if (!this.IsCancellationRequested) { int num = Thread.CurrentThread.ManagedThreadId % CancellationTokenSource.s_nLists; CancellationCallbackInfo cancellationCallbackInfo = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this); SparselyPopulatedArray<CancellationCallbackInfo>[] array = this.m_registeredCallbacksLists; if (array == null) { SparselyPopulatedArray<CancellationCallbackInfo>[] array2 = new SparselyPopulatedArray<CancellationCallbackInfo>[CancellationTokenSource.s_nLists]; array = Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>[]>(ref this.m_registeredCallbacksLists, array2, null); if (array == null) { array = array2; } } SparselyPopulatedArray<CancellationCallbackInfo> sparselyPopulatedArray = Volatile.Read<SparselyPopulatedArray<CancellationCallbackInfo>>(ref array[num]); if (sparselyPopulatedArray == null) { SparselyPopulatedArray<CancellationCallbackInfo> value = new SparselyPopulatedArray<CancellationCallbackInfo>(4); Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>>(ref array[num], value, null); sparselyPopulatedArray = array[num]; } SparselyPopulatedArrayAddInfo<CancellationCallbackInfo> registrationInfo = sparselyPopulatedArray.Add(cancellationCallbackInfo); CancellationTokenRegistration result = new CancellationTokenRegistration(cancellationCallbackInfo, registrationInfo); if (!this.IsCancellationRequested) { return result; } if (!result.TryDeregister()) { return result; } } callback(stateForCallback); return default(CancellationTokenRegistration); }
internal CancellationTokenRegistration InternalRegister(Action<object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext) { ThrowIfDisposed(); if (!IsCancellationRequested) { var index = Thread.CurrentThread.ManagedThreadId % _nLists; var element = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this); var registeredCallbacksLists = _registeredCallbacksLists; if (registeredCallbacksLists == null) { var arrayArray2 = new SparselyPopulatedArray<CancellationCallbackInfo>[_nLists]; registeredCallbacksLists = Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>[]>(ref _registeredCallbacksLists, arrayArray2, null); if (registeredCallbacksLists == null) registeredCallbacksLists = arrayArray2; } var array = Volatile.Read<SparselyPopulatedArray<CancellationCallbackInfo>>(ref registeredCallbacksLists[index]); if (array == null) { var array2 = new SparselyPopulatedArray<CancellationCallbackInfo>(4); Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>>(ref registeredCallbacksLists[index], array2, null); array = registeredCallbacksLists[index]; } var registrationInfo = array.Add(element); var registration = new CancellationTokenRegistration(element, registrationInfo); if (!IsCancellationRequested) return registration; if (!registration.TryDeregister()) return registration; } callback(stateForCallback); return new CancellationTokenRegistration(); }