Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / ThreadNeutralSemaphore.cs / 1 / ThreadNeutralSemaphore.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Collections.Generic; using System.Diagnostics; using System.Threading; class ThreadNeutralSemaphore { #if DEBUG_EXPENSIVE StackTrace exitStack; #endif int count; int maxCount; Queuewaiters; bool aborted; object ThisLock = new object(); public ThreadNeutralSemaphore(int maxCount) { if (maxCount < 1) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxCount", maxCount, SR.GetString(SR.ValueMustBePositive))); this.maxCount = maxCount; } Queue Waiters { get { if (waiters == null) { waiters = new Queue (); } return waiters; } } public bool TryEnter() { lock (ThisLock) { if (this.count < this.maxCount) { this.count++; return true; } return false; } } public bool Enter(WaitCallback callback, object state) { if (callback == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("callback"); lock (ThisLock) { if (this.count < this.maxCount) { this.count++; return true; } Waiters.Enqueue(new AsyncWaiter(callback, state)); return false; } } public void Enter() { SyncWaiter waiter = EnterCore(); if (waiter != null) waiter.Wait(); } public bool TryEnter(TimeSpan timeout) { SyncWaiter waiter = EnterCore(); if (waiter != null) { return waiter.Wait(timeout); } else { return true; } } public void Enter(TimeSpan timeout) { if (!TryEnter(timeout)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateEnterTimedOutException(timeout)); } } internal static TimeoutException CreateEnterTimedOutException(TimeSpan timeout) { return new TimeoutException(SR.GetString(SR.ThreadAcquisitionTimedOut, timeout)); } static CommunicationObjectAbortedException CreateObjectAbortedException() { return new CommunicationObjectAbortedException(SR.GetString(SR.ThreadNeutralSemaphoreAborted)); } // remove a waiter from our queue. Returns true if successful. Used to implement timeouts. bool RemoveWaiter(Waiter waiter) { bool removed = false; lock (ThisLock) { for (int i = Waiters.Count; i > 0; i--) { Waiter temp = Waiters.Dequeue(); if (object.ReferenceEquals(temp, waiter)) { removed = true; } else { Waiters.Enqueue(temp); } } } return removed; } SyncWaiter EnterCore() { SyncWaiter waiter; lock (ThisLock) { if (this.aborted) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ThreadNeutralSemaphore.CreateObjectAbortedException()); } if (this.count < this.maxCount) { this.count++; return null; } waiter = new SyncWaiter(this); Waiters.Enqueue(waiter); } return waiter; } public void Exit() { Waiter waiter; lock (ThisLock) { if (this.count == 0) { string message = SR.GetString(SR.InvalidLockOperation); #if DEBUG_EXPENSIVE if (exitStack != null) { string originalStack = exitStack.ToString().Replace("\r\n", "\r\n "); message = SR.GetString(SR.InvalidLockOperationStack, originalStack); } #endif throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SynchronizationLockException(message)); } if (waiters == null || waiters.Count == 0) { this.count--; #if DEBUG_EXPENSIVE if (this.count == 0) { exitStack = new StackTrace(); } #endif return; } waiter = waiters.Dequeue(); } waiter.Signal(); } /// /// Abort the ThreadNeutralSemaphore object. /// NOTE: This method is only supported for sync waiters. /// public void Abort() { lock (ThisLock) { if (aborted) { return; } aborted = true; if (waiters != null) { while (waiters.Count > 0) { Waiter waiter = waiters.Dequeue(); waiter.Abort(); } } } } abstract class Waiter { public abstract void Signal(); public abstract void Abort(); } class AsyncWaiter : Waiter { WaitCallback callback; object state; public AsyncWaiter(WaitCallback callback, object state) { this.callback = callback; this.state = state; } public override void Signal() { IOThreadScheduler.ScheduleCallback(callback, state); } public override void Abort() { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.ThreadNeutralSemaphoreAsyncAbort))); } } class SyncWaiter : Waiter { ThreadNeutralSemaphore parent; AutoResetEvent waitHandle; bool aborted; public SyncWaiter(ThreadNeutralSemaphore parent) { this.waitHandle = new AutoResetEvent(false); this.parent = parent; } public void Wait() { waitHandle.WaitOne(); waitHandle.Close(); if (this.aborted) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ThreadNeutralSemaphore.CreateObjectAbortedException()); } } public bool Wait(TimeSpan timeout) { bool result = true; if (!TimeoutHelper.WaitOne(waitHandle, timeout, false)) { if (!parent.RemoveWaiter(this)) { waitHandle.WaitOne(); } else { result = false; } } waitHandle.Close(); if (this.aborted) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ThreadNeutralSemaphore.CreateObjectAbortedException()); } return result; } public override void Signal() { waitHandle.Set(); } public override void Abort() { this.aborted = true; waitHandle.Set(); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ErrorWebPart.cs
- ValidationHelpers.cs
- AssemblyBuilder.cs
- TriggerActionCollection.cs
- EndpointDiscoveryElement.cs
- LinkedResourceCollection.cs
- SerializationSectionGroup.cs
- PolyBezierSegment.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- EncodingInfo.cs
- Table.cs
- _TransmitFileOverlappedAsyncResult.cs
- DragSelectionMessageFilter.cs
- AssemblyCollection.cs
- DbDataAdapter.cs
- ListBoxItemWrapperAutomationPeer.cs
- ExpressionBuilderContext.cs
- Tokenizer.cs
- FlowDocumentFormatter.cs
- UnmanagedMarshal.cs
- _NetRes.cs
- ToggleProviderWrapper.cs
- NumericUpDown.cs
- InvalidChannelBindingException.cs
- StringInfo.cs
- PopupControlService.cs
- MarshalDirectiveException.cs
- OleCmdHelper.cs
- HMACSHA512.cs
- PanelContainerDesigner.cs
- WebPartDescriptionCollection.cs
- EntityViewContainer.cs
- WebConfigurationFileMap.cs
- OracleSqlParser.cs
- PersonalizationDictionary.cs
- PeerNameResolver.cs
- DescendantQuery.cs
- BufferedGraphicsContext.cs
- CharStorage.cs
- BitmapImage.cs
- PromptBuilder.cs
- CharacterShapingProperties.cs
- TextSelection.cs
- SqlCacheDependencySection.cs
- LinkedResource.cs
- LineVisual.cs
- DockPanel.cs
- PersonalizationProvider.cs
- Normalization.cs
- SqlTypeConverter.cs
- ApplicationBuildProvider.cs
- BitmapFrame.cs
- SmiXetterAccessMap.cs
- CategoryState.cs
- ZoneLinkButton.cs
- AssociationEndMember.cs
- Set.cs
- Section.cs
- COM2PictureConverter.cs
- FileDialog.cs
- StrokeNode.cs
- ResourceExpressionBuilder.cs
- HttpWebRequest.cs
- DynamicPropertyReader.cs
- _BasicClient.cs
- AnimatedTypeHelpers.cs
- BitStack.cs
- RegisteredDisposeScript.cs
- SiteMapDataSource.cs
- XmlSignificantWhitespace.cs
- LinearGradientBrush.cs
- APCustomTypeDescriptor.cs
- IResourceProvider.cs
- FocusTracker.cs
- DataGridCell.cs
- FileSecurity.cs
- InstallHelper.cs
- DateTimeUtil.cs
- FaultHandlingFilter.cs
- ZoneLinkButton.cs
- RecognizedWordUnit.cs
- mactripleDES.cs
- RegexTypeEditor.cs
- TaskResultSetter.cs
- GroupBox.cs
- BooleanExpr.cs
- LocalTransaction.cs
- ConfigUtil.cs
- Privilege.cs
- AQNBuilder.cs
- StandardOleMarshalObject.cs
- DbConnectionPoolIdentity.cs
- ToolStripManager.cs
- NativeMethods.cs
- XmlUtil.cs
- FlowLayout.cs
- SignatureToken.cs
- ImageList.cs
- LogEntryHeaderDeserializer.cs
- ChameleonKey.cs