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
- ProcessProtocolHandler.cs
- ISFTagAndGuidCache.cs
- XsltConvert.cs
- ZipIOBlockManager.cs
- GrammarBuilderBase.cs
- OleDbParameterCollection.cs
- DynamicQueryableWrapper.cs
- TextBoxBase.cs
- SimpleColumnProvider.cs
- MenuRendererClassic.cs
- GenericUriParser.cs
- DataGridViewDataErrorEventArgs.cs
- CollectionBase.cs
- CookieParameter.cs
- BitmapEffectInputConnector.cs
- BindingBase.cs
- PtsContext.cs
- SocketInformation.cs
- ListViewGroupItemCollection.cs
- TabControlCancelEvent.cs
- DataGridViewIntLinkedList.cs
- NamedElement.cs
- IdentityValidationException.cs
- input.cs
- XomlCompilerParameters.cs
- AutomationIdentifierGuids.cs
- WebSysDisplayNameAttribute.cs
- LZCodec.cs
- ErrorFormatterPage.cs
- ConfigurationErrorsException.cs
- UserNameSecurityTokenProvider.cs
- RectConverter.cs
- HttpCacheVaryByContentEncodings.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- KeyEvent.cs
- SecurityElement.cs
- ListDictionaryInternal.cs
- HeaderCollection.cs
- SafeRightsManagementQueryHandle.cs
- ModelVisual3D.cs
- RenderDataDrawingContext.cs
- WorkflowDesignerColors.cs
- Win32MouseDevice.cs
- CustomServiceCredentials.cs
- CompiledXpathExpr.cs
- _DynamicWinsockMethods.cs
- NameNode.cs
- OleAutBinder.cs
- ColumnMapTranslator.cs
- InputElement.cs
- ActionMessageFilter.cs
- SubMenuStyleCollection.cs
- ObjectContextServiceProvider.cs
- hwndwrapper.cs
- KeyValuePairs.cs
- NumericExpr.cs
- FixedSOMContainer.cs
- WsatServiceAddress.cs
- PingReply.cs
- FormsAuthenticationEventArgs.cs
- TypedTableBase.cs
- SpellerHighlightLayer.cs
- HttpCacheParams.cs
- CalendarDateRange.cs
- EventLogPermission.cs
- XmlChildNodes.cs
- FixedHyperLink.cs
- PageThemeBuildProvider.cs
- ModuleConfigurationInfo.cs
- ConnectionStringEditor.cs
- TextBoxAutomationPeer.cs
- FixedElement.cs
- Baml2006ReaderSettings.cs
- ListViewGroupConverter.cs
- DefaultExpression.cs
- EasingKeyFrames.cs
- CmsInterop.cs
- ListViewItem.cs
- TimeoutException.cs
- DefaultMemberAttribute.cs
- ListBindingHelper.cs
- NumberFunctions.cs
- ReferencedAssembly.cs
- X509ChainPolicy.cs
- ScrollChrome.cs
- JsonXmlDataContract.cs
- XmlNamespaceManager.cs
- XmlSchemaException.cs
- Splitter.cs
- AnimationLayer.cs
- EncoderBestFitFallback.cs
- InputLanguageProfileNotifySink.cs
- Point4D.cs
- ExeConfigurationFileMap.cs
- DataSourceXmlSerializationAttribute.cs
- FileDataSourceCache.cs
- RectangleGeometry.cs
- NativeCompoundFileAPIs.cs
- ContainerAction.cs
- SamlAttributeStatement.cs