Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Threading / CancellationTokenRegistration.cs / 1305376 / CancellationTokenRegistration.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // //[....] //////////////////////////////////////////////////////////////////////////////// using System.Diagnostics.Contracts; using System.Security.Permissions; namespace System.Threading { ////// Represents a callback delegate that has been registered with a ///CancellationToken . ////// To unregister a callback, dispose the corresponding Registration instance. /// [HostProtection(Synchronization = true, ExternalThreading = true)] public struct CancellationTokenRegistration : IEquatable, IDisposable { private readonly CancellationTokenSource m_tokenSource; private readonly CancellationCallbackInfo m_callbackInfo; private readonly SparselyPopulatedArrayAddInfo m_registrationInfo; internal CancellationTokenRegistration( CancellationTokenSource tokenSource, CancellationCallbackInfo callbackInfo, SparselyPopulatedArrayAddInfo registrationInfo) { m_tokenSource = tokenSource; m_callbackInfo = callbackInfo; m_registrationInfo = registrationInfo; } /// /// Attempts to deregister the item. If it's already being run, this may fail. /// Entails a full memory fence. /// ///True if the callback was found and deregistered, false otherwise. internal bool TryDeregister() { if (m_registrationInfo.Source == null) //can be null for dummy registrations. return false; // Try to remove the callback info from the array. // It is possible the callback info is missing (removed for run, or removed by someone else) // It is also possible there is info in the array but it doesn't match our current registration's callback info. CancellationCallbackInfo prevailingCallbackInfoInSlot = m_registrationInfo.Source.SafeAtomicRemove(m_registrationInfo.Index, m_callbackInfo); if (prevailingCallbackInfoInSlot != m_callbackInfo) return false; //the callback in the slot wasn't us. return true; } ////// Disposes of the registration and unregisters the target callback from the associated /// public void Dispose() { // If the token source has been disposed, we must throw. if (m_tokenSource != null) m_tokenSource.ThrowIfDisposed(); // Remove the entry from the array. // This call includes a full memory fence which prevents potential reorderings of the reads below bool deregisterOccured = TryDeregister(); // We guarantee that we will not return if the callback is being executed (assuming we are not currently called by the callback itself) // We achieve this by the following rules: // 1. if we are called in the context of an executing callback, no need to wait (determined by tracking callback-executor threadID) // - if the currently executing callback is this CTR, then waiting would deadlock. (We choose to return rather than deadlock) // - if not, then this CTR cannot be the one executing, hence no need to wait // // 2. if deregistration failed, and we are on a different thread, then the callback may be running under control of cts.Cancel() // => poll until cts.ExecutingCallback is not the one we are trying to deregister. if (m_tokenSource != null && m_tokenSource.IsCancellationRequested && //running callbacks has commenced. ! m_tokenSource.IsCancellationCompleted && //running callbacks hasn't finished !deregisterOccured && //deregistration failed (ie the callback is missing from the list) m_tokenSource.ThreadIDExecutingCallbacks != Thread.CurrentThread.ManagedThreadId) //the executingThreadID is not this threadID. { // Callback execution is in progress, the executing thread is different to us and has taken the callback for execution // so observe and wait until this target callback is no longer the executing callback. m_tokenSource.WaitForCallbackToComplete(m_callbackInfo); } } ///CancellationToken . /// If the target callback is currently executing this method will wait until it completes, except /// in the degenerate cases where a callback method deregisters itself. ////// Determines whether two /// The first instance. /// The second instance. ///CancellationTokenRegistration /// instances are equal. ///True if the instances are equal; otherwise, false. public static bool operator ==(CancellationTokenRegistration left, CancellationTokenRegistration right) { return left.Equals(right); } ////// Determines whether two /// The first instance. /// The second instance. ///CancellationTokenRegistration instances are not equal. ///True if the instances are not equal; otherwise, false. public static bool operator !=(CancellationTokenRegistration left, CancellationTokenRegistration right) { return !left.Equals(right); } ////// Determines whether the current /// The other object to which to compare this instance. ///CancellationTokenRegistration instance is equal to the /// specified. /// True, if both this and public override bool Equals(object obj) { return ((obj is CancellationTokenRegistration) && Equals((CancellationTokenRegistration) obj)); } ///are equal. False, otherwise. /// Two CancellationTokenRegistration instances are equal if /// they both refer to the output of a single call to the same Register method of a ///CancellationToken . ////// Determines whether the current /// The otherCancellationToken instance is equal to the /// specified. /// CancellationTokenRegistration to which to compare this instance. ///True, if both this and public bool Equals(CancellationTokenRegistration other) { return m_tokenSource == other.m_tokenSource && m_callbackInfo == other.m_callbackInfo && m_registrationInfo.Source == other.m_registrationInfo.Source && m_registrationInfo.Index == other.m_registrationInfo.Index; } ///are equal. False, otherwise. /// Two CancellationTokenRegistration instances are equal if /// they both refer to the output of a single call to the same Register method of a ///CancellationToken . ////// Serves as a hash function for a ///CancellationTokenRegistration. . ///A hash code for the current public override int GetHashCode() { if (m_registrationInfo.Source != null) return m_registrationInfo.Source.GetHashCode() ^ m_registrationInfo.Index.GetHashCode(); return m_registrationInfo.Index.GetHashCode(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // //CancellationTokenRegistration instance.[....] //////////////////////////////////////////////////////////////////////////////// using System.Diagnostics.Contracts; using System.Security.Permissions; namespace System.Threading { ////// Represents a callback delegate that has been registered with a ///CancellationToken . ////// To unregister a callback, dispose the corresponding Registration instance. /// [HostProtection(Synchronization = true, ExternalThreading = true)] public struct CancellationTokenRegistration : IEquatable, IDisposable { private readonly CancellationTokenSource m_tokenSource; private readonly CancellationCallbackInfo m_callbackInfo; private readonly SparselyPopulatedArrayAddInfo m_registrationInfo; internal CancellationTokenRegistration( CancellationTokenSource tokenSource, CancellationCallbackInfo callbackInfo, SparselyPopulatedArrayAddInfo registrationInfo) { m_tokenSource = tokenSource; m_callbackInfo = callbackInfo; m_registrationInfo = registrationInfo; } /// /// Attempts to deregister the item. If it's already being run, this may fail. /// Entails a full memory fence. /// ///True if the callback was found and deregistered, false otherwise. internal bool TryDeregister() { if (m_registrationInfo.Source == null) //can be null for dummy registrations. return false; // Try to remove the callback info from the array. // It is possible the callback info is missing (removed for run, or removed by someone else) // It is also possible there is info in the array but it doesn't match our current registration's callback info. CancellationCallbackInfo prevailingCallbackInfoInSlot = m_registrationInfo.Source.SafeAtomicRemove(m_registrationInfo.Index, m_callbackInfo); if (prevailingCallbackInfoInSlot != m_callbackInfo) return false; //the callback in the slot wasn't us. return true; } ////// Disposes of the registration and unregisters the target callback from the associated /// public void Dispose() { // If the token source has been disposed, we must throw. if (m_tokenSource != null) m_tokenSource.ThrowIfDisposed(); // Remove the entry from the array. // This call includes a full memory fence which prevents potential reorderings of the reads below bool deregisterOccured = TryDeregister(); // We guarantee that we will not return if the callback is being executed (assuming we are not currently called by the callback itself) // We achieve this by the following rules: // 1. if we are called in the context of an executing callback, no need to wait (determined by tracking callback-executor threadID) // - if the currently executing callback is this CTR, then waiting would deadlock. (We choose to return rather than deadlock) // - if not, then this CTR cannot be the one executing, hence no need to wait // // 2. if deregistration failed, and we are on a different thread, then the callback may be running under control of cts.Cancel() // => poll until cts.ExecutingCallback is not the one we are trying to deregister. if (m_tokenSource != null && m_tokenSource.IsCancellationRequested && //running callbacks has commenced. ! m_tokenSource.IsCancellationCompleted && //running callbacks hasn't finished !deregisterOccured && //deregistration failed (ie the callback is missing from the list) m_tokenSource.ThreadIDExecutingCallbacks != Thread.CurrentThread.ManagedThreadId) //the executingThreadID is not this threadID. { // Callback execution is in progress, the executing thread is different to us and has taken the callback for execution // so observe and wait until this target callback is no longer the executing callback. m_tokenSource.WaitForCallbackToComplete(m_callbackInfo); } } ///CancellationToken . /// If the target callback is currently executing this method will wait until it completes, except /// in the degenerate cases where a callback method deregisters itself. ////// Determines whether two /// The first instance. /// The second instance. ///CancellationTokenRegistration /// instances are equal. ///True if the instances are equal; otherwise, false. public static bool operator ==(CancellationTokenRegistration left, CancellationTokenRegistration right) { return left.Equals(right); } ////// Determines whether two /// The first instance. /// The second instance. ///CancellationTokenRegistration instances are not equal. ///True if the instances are not equal; otherwise, false. public static bool operator !=(CancellationTokenRegistration left, CancellationTokenRegistration right) { return !left.Equals(right); } ////// Determines whether the current /// The other object to which to compare this instance. ///CancellationTokenRegistration instance is equal to the /// specified. /// True, if both this and public override bool Equals(object obj) { return ((obj is CancellationTokenRegistration) && Equals((CancellationTokenRegistration) obj)); } ///are equal. False, otherwise. /// Two CancellationTokenRegistration instances are equal if /// they both refer to the output of a single call to the same Register method of a ///CancellationToken . ////// Determines whether the current /// The otherCancellationToken instance is equal to the /// specified. /// CancellationTokenRegistration to which to compare this instance. ///True, if both this and public bool Equals(CancellationTokenRegistration other) { return m_tokenSource == other.m_tokenSource && m_callbackInfo == other.m_callbackInfo && m_registrationInfo.Source == other.m_registrationInfo.Source && m_registrationInfo.Index == other.m_registrationInfo.Index; } ///are equal. False, otherwise. /// Two CancellationTokenRegistration instances are equal if /// they both refer to the output of a single call to the same Register method of a ///CancellationToken . ////// Serves as a hash function for a ///CancellationTokenRegistration. . ///A hash code for the current public override int GetHashCode() { if (m_registrationInfo.Source != null) return m_registrationInfo.Source.GetHashCode() ^ m_registrationInfo.Index.GetHashCode(); return m_registrationInfo.Index.GetHashCode(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.CancellationTokenRegistration instance.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MemberDescriptor.cs
- DataGridItemEventArgs.cs
- PropertyEntry.cs
- PhysicalAddress.cs
- EdmRelationshipNavigationPropertyAttribute.cs
- EncodingDataItem.cs
- QilTernary.cs
- DiscardableAttribute.cs
- SqlConnectionStringBuilder.cs
- PartitionerStatic.cs
- EncryptedPackageFilter.cs
- AmbientEnvironment.cs
- AmbientLight.cs
- GZipObjectSerializer.cs
- MergeFilterQuery.cs
- IndentedTextWriter.cs
- WebPartZone.cs
- FontInfo.cs
- SafeLibraryHandle.cs
- SqlClientMetaDataCollectionNames.cs
- LinkLabelLinkClickedEvent.cs
- ICspAsymmetricAlgorithm.cs
- UriExt.cs
- XamlBrushSerializer.cs
- EntityDescriptor.cs
- ObjectDataProvider.cs
- ListViewSelectEventArgs.cs
- ImportException.cs
- EntityObject.cs
- EntityDataSourceWrapper.cs
- ServiceMetadataExtension.cs
- GridViewColumnCollection.cs
- MessageSecurityOverMsmqElement.cs
- DataContractJsonSerializer.cs
- RegularExpressionValidator.cs
- Operand.cs
- WebControlsSection.cs
- XmlMapping.cs
- AssemblyAssociatedContentFileAttribute.cs
- ConsoleTraceListener.cs
- DesignerAttribute.cs
- ContextMenu.cs
- Part.cs
- ErrorLog.cs
- ResourcePool.cs
- PolicyException.cs
- TreeNodeStyleCollection.cs
- FrameSecurityDescriptor.cs
- SQLInt64.cs
- XmlNodeReader.cs
- ModelFunctionTypeElement.cs
- CompositeFontInfo.cs
- HitTestResult.cs
- Compress.cs
- DefaultParameterValueAttribute.cs
- ConnectionOrientedTransportBindingElement.cs
- DataGridHeaderBorder.cs
- XmlSchemaInferenceException.cs
- RadioButton.cs
- CapacityStreamGeometryContext.cs
- DesignTimeTemplateParser.cs
- XPathDocumentNavigator.cs
- PathFigureCollection.cs
- WebPartEditorApplyVerb.cs
- NativeConfigurationLoader.cs
- ImageField.cs
- RoutingConfiguration.cs
- ToolStripLabel.cs
- IProducerConsumerCollection.cs
- ITextView.cs
- SafeProcessHandle.cs
- ArraySortHelper.cs
- DataViewSetting.cs
- SqlCacheDependency.cs
- XmlWriterTraceListener.cs
- ReaderContextStackData.cs
- QuaternionAnimationBase.cs
- TemplatePagerField.cs
- ResourceReferenceKeyNotFoundException.cs
- TimeoutTimer.cs
- LogEntryHeaderSerializer.cs
- ObjectViewListener.cs
- formatstringdialog.cs
- TextWriterTraceListener.cs
- CategoryValueConverter.cs
- ConfigurationStrings.cs
- PipelineModuleStepContainer.cs
- SelectorItemAutomationPeer.cs
- nulltextnavigator.cs
- ClientBuildManager.cs
- DataRow.cs
- PeerInvitationResponse.cs
- InfoCardClaimCollection.cs
- CollectionChangeEventArgs.cs
- StopRoutingHandler.cs
- ByteAnimationBase.cs
- InstalledFontCollection.cs
- HtmlTableRowCollection.cs
- ValueTypeFixupInfo.cs
- CultureTable.cs