Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / ListenerHandler.cs / 1 / ListenerHandler.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.Dispatcher { using System; using System.ServiceModel; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; using System.ServiceModel.Channels; using System.ServiceModel.Diagnostics; using System.Threading; using System.Transactions; using SessionIdleManager = System.ServiceModel.Channels.ServiceChannel.SessionIdleManager; class ListenerHandler : CommunicationObject, ISessionThrottleNotification { static AsyncCallback acceptCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(ListenerHandler.AcceptCallback)); static WaitCallback initiateChannelPump = new WaitCallback(ListenerHandler.InitiateChannelPump); readonly ErrorHandlingAcceptor acceptor; readonly ChannelDispatcher channelDispatcher; ListenerChannel channel; SessionIdleManager idleManager; bool acceptedNull; bool doneAccepting; EndpointDispatcherTable endpoints; readonly ServiceHostBase host; readonly IListenerBinder listenerBinder; readonly ServiceThrottle throttle; IDefaultCommunicationTimeouts timeouts; static TimeSpan transactionalTimeout { get { return TimeSpan.FromSeconds(5); } } WrappedTransaction wrappedTransaction; internal ListenerHandler(IListenerBinder listenerBinder, ChannelDispatcher channelDispatcher, ServiceHostBase host, ServiceThrottle throttle, IDefaultCommunicationTimeouts timeouts) { this.listenerBinder = listenerBinder; if (!((this.listenerBinder != null))) { DiagnosticUtility.DebugAssert("ListenerHandler.ctor: (this.listenerBinder != null)"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("listenerBinder"); } this.channelDispatcher = channelDispatcher; if (!((this.channelDispatcher != null))) { DiagnosticUtility.DebugAssert("ListenerHandler.ctor: (this.channelDispatcher != null)"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("channelDispatcher"); } this.host = host; if (!((this.host != null))) { DiagnosticUtility.DebugAssert("ListenerHandler.ctor: (this.host != null)"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("host"); } this.throttle = throttle; if (!((this.throttle != null))) { DiagnosticUtility.DebugAssert("ListenerHandler.ctor: (this.throttle != null)"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("throttle"); } this.timeouts = timeouts; this.endpoints = channelDispatcher.EndpointDispatcherTable; this.acceptor = new ErrorHandlingAcceptor(listenerBinder, channelDispatcher); } internal ChannelDispatcher ChannelDispatcher { get { return this.channelDispatcher; } } internal ListenerChannel Channel { get { return this.channel; } } protected override TimeSpan DefaultCloseTimeout { get { return this.host.CloseTimeout; } } protected override TimeSpan DefaultOpenTimeout { get { return this.host.OpenTimeout; } } internal EndpointDispatcherTable Endpoints { get { return this.endpoints; } set { this.endpoints = value; } } internal ServiceHostBase Host { get { return this.host; } } new internal object ThisLock { get { return base.ThisLock; } } protected override void OnOpen(TimeSpan timeout) { } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { return new CompletedAsyncResult(callback, state); } protected override void OnEndOpen(IAsyncResult result) { CompletedAsyncResult.End(result); } protected override void OnOpened() { base.OnOpened(); this.channelDispatcher.Channels.IncrementActivityCount(); NewChannelPump(); } internal void NewChannelPump() { IOThreadScheduler.ScheduleCallback(ListenerHandler.initiateChannelPump, this); } static void InitiateChannelPump(object state) { ListenerHandler listenerHandler = state as ListenerHandler; if (listenerHandler.ChannelDispatcher.IsTransactedAccept) { listenerHandler.TransactedChannelPump(); } else { listenerHandler.ChannelPump(); } } void ChannelPump() { IChannelListener listener = this.listenerBinder.Listener; for (;;) { if (this.acceptedNull || (listener.State == CommunicationState.Faulted)) { this.DoneAccepting(); break; } if (!this.Accept() || !this.AcquireThrottle()) { break; } this.Dispatch(); } } [MethodImpl(MethodImplOptions.NoInlining)] void TransactedChannelPump() { IChannelListener listener = this.listenerBinder.Listener; for (;;) { if (this.acceptedNull || (listener.State == CommunicationState.Faulted)) { this.DoneAccepting(); break; } this.acceptor.WaitForChannel(); Transaction tx; if (this.TransactedAccept(out tx)) { if (null != tx) { this.wrappedTransaction = new WrappedTransaction(tx); if (!this.AcquireThrottle()) break; this.Dispatch(); } } } } void AbortChannels() { IChannel[] channels = this.channelDispatcher.Channels.ToArray(); for (int index = 0; index < channels.Length; index++) { channels[index].Abort(); } } bool Accept() { IAsyncResult result = this.acceptor.BeginTryAccept(TimeSpan.MaxValue, ListenerHandler.acceptCallback, this); return result.CompletedSynchronously && (this.channel != null); } bool TransactedAccept(out Transaction tx) { tx = null; try { tx = TransactionBehavior.CreateTransaction(this.ChannelDispatcher.TransactionIsolationLevel, this.ChannelDispatcher.TransactionTimeout); IChannelBinder binder = null; using (TransactionScope scope = new TransactionScope(tx)) { if (!this.acceptor.TryAccept(transactionalTimeout, out binder)) { return false; } scope.Complete(); } if (null != binder) { this.channel = new ListenerChannel(binder); this.idleManager = SessionIdleManager.CreateIfNeeded(this.channel.Binder, this.channelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout); return true; } else { this.AcceptedNull(); tx = null; return false; } } catch (CommunicationException e) { if (null != tx) { try { tx.Rollback(); } catch (TransactionException ex) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(ex, TraceEventType.Information); } } } tx = null; if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } return false; } catch (TransactionException e) { tx = null; if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } return false; } } ListenerChannel CompleteAccept(IAsyncResult result) { IChannelBinder binder; bool valid = this.acceptor.EndTryAccept(result, out binder); if (valid) { if (binder != null) { return new ListenerChannel(binder); } else { this.AcceptedNull(); return null; } } else { return null; } } static void AcceptCallback(IAsyncResult result) { ((ListenerHandler)result.AsyncState).AcceptReady(result); } void AcceptReady(IAsyncResult result) { this.channel = this.CompleteAccept(result); if (this.channel != null) { DiagnosticUtility.DebugAssert(this.idleManager == null, "There cannot be an existing idle manager"); this.idleManager = SessionIdleManager.CreateIfNeeded(this.channel.Binder, this.channelDispatcher.DefaultCommunicationTimeouts.ReceiveTimeout); } // If we didn't complete synchronously, this is a clean threadpool thread bool cleanThread = !result.CompletedSynchronously; if (this.channel == null) { this.DoneAccepting(); return; } if (cleanThread && this.AcquireThrottle()) { this.Dispatch(); this.ChannelPump(); } } bool AcquireThrottle() { if ((this.channel != null) && (this.throttle != null) && (this.channelDispatcher.Session)) { return this.throttle.AcquireSession(this); } return true; } // This callback always occurs async and always on a dirty thread public void ThrottleAcquired() { this.Dispatch(); this.NewChannelPump(); } void CloseChannel(IChannel channel, TimeSpan timeout) { try { if (channel.State != CommunicationState.Closing && channel.State != CommunicationState.Closed) { CloseChannelState state = new CloseChannelState(this, channel); if (channel is ISessionChannel) { IDuplexSession duplexSession = ((ISessionChannel )channel).Session; IAsyncResult result = duplexSession.BeginCloseOutputSession(timeout, DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(CloseOutputSessionCallback)), state); if (result.CompletedSynchronously) duplexSession.EndCloseOutputSession(result); } else { IAsyncResult result = channel.BeginClose(timeout, DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(CloseChannelCallback)), state); if (result.CompletedSynchronously) channel.EndClose(result); } } } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } this.HandleError(e); if (channel is ISessionChannel ) { channel.Abort(); } } } static void CloseChannelCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseChannelState state = (CloseChannelState)result.AsyncState; try { state.Channel.EndClose(result); } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } state.ListenerHandler.HandleError(e); } } public void CloseInput(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // Close all datagram channels IChannel[] channels = this.channelDispatcher.Channels.ToArray(); for (int index = 0; index < channels.Length; index++) { IChannel channel = channels[index]; if (!this.IsSessionChannel(channel)) { try { channel.Close(timeoutHelper.RemainingTime()); } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } this.HandleError(e); } } } } static void CloseOutputSessionCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } CloseChannelState state = (CloseChannelState)result.AsyncState; try { ((ISessionChannel )state.Channel).Session.EndCloseOutputSession(result); } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } state.ListenerHandler.HandleError(e); state.Channel.Abort(); } } void CloseChannels(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); IChannel[] channels = this.channelDispatcher.Channels.ToArray(); for (int index = 0; index < channels.Length; index++) CloseChannel(channels[index], timeoutHelper.RemainingTime()); } void Dispatch() { ListenerChannel channel = this.channel; SessionIdleManager idleManager = this.idleManager; this.channel = null; this.idleManager = null; try { if (channel != null) { ChannelHandler handler = new ChannelHandler(listenerBinder.MessageVersion, channel.Binder, this.throttle, this, (channel.Throttle != null), this.wrappedTransaction, idleManager); if (!channel.Binder.HasSession) { this.channelDispatcher.Channels.Add(channel.Binder.Channel); } if (channel.Binder is DuplexChannelBinder) { DuplexChannelBinder duplexChannelBinder = channel.Binder as DuplexChannelBinder; duplexChannelBinder.ChannelHandler = handler; duplexChannelBinder.DefaultCloseTimeout = this.DefaultCloseTimeout; if (this.timeouts == null) duplexChannelBinder.DefaultSendTimeout = ServiceDefaults.SendTimeout; else duplexChannelBinder.DefaultSendTimeout = timeouts.SendTimeout; } ChannelHandler.Register(handler); channel = null; idleManager = null; } } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } this.HandleError(e); } finally { if (channel != null) { channel.Binder.Channel.Abort(); if (this.throttle != null && this.channelDispatcher.Session) { this.throttle.DeactivateChannel(); } if (idleManager != null) { idleManager.CancelTimer(); } } } } void AcceptedNull() { this.acceptedNull = true; } void DoneAccepting() { lock (this.ThisLock) { if (!this.doneAccepting) { this.doneAccepting = true; this.channelDispatcher.Channels.DecrementActivityCount(); } } } bool IsSessionChannel(IChannel channel) { return (channel is ISessionChannel || channel is ISessionChannel || channel is ISessionChannel ); } void CancelPendingIdleManager() { SessionIdleManager idleManager = this.idleManager; if (idleManager != null) { idleManager.CancelTimer(); } } protected override void OnAbort() { // if there's an idle manager that has not been transferred to the channel handler, cancel it CancelPendingIdleManager(); // Start aborting incoming channels this.channelDispatcher.Channels.CloseInput(); // Abort existing channels this.AbortChannels(); // Wait for channels to finish aborting this.channelDispatcher.Channels.Abort(); } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // if there's an idle manager that has not been cancelled, cancel it CancelPendingIdleManager(); // Start aborting incoming channels this.channelDispatcher.Channels.CloseInput(); // Start closing existing channels this.CloseChannels(timeoutHelper.RemainingTime()); // Wait for channels to finish closing return this.channelDispatcher.Channels.BeginClose(timeoutHelper.RemainingTime(), callback, state); } protected override void OnClose(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // if there's an idle manager that has not been cancelled, cancel it CancelPendingIdleManager(); // Start aborting incoming channels this.channelDispatcher.Channels.CloseInput(); // Start closing existing channels this.CloseChannels(timeoutHelper.RemainingTime()); // Wait for channels to finish closing this.channelDispatcher.Channels.Close(timeoutHelper.RemainingTime()); } protected override void OnEndClose(IAsyncResult result) { this.channelDispatcher.Channels.EndClose(result); } bool HandleError(Exception e) { return this.channelDispatcher.HandleError(e); } class CloseChannelState { ListenerHandler listenerHandler; IChannel channel; internal CloseChannelState(ListenerHandler listenerHandler, IChannel channel) { this.listenerHandler = listenerHandler; this.channel = channel; } internal ListenerHandler ListenerHandler { get { return this.listenerHandler; } } internal IChannel Channel { get { return this.channel; } } } } class ListenerChannel { IChannelBinder binder; ServiceThrottle throttle; public ListenerChannel(IChannelBinder binder) { this.binder = binder; } public IChannelBinder Binder { get { return this.binder; } } public ServiceThrottle Throttle { get { return this.throttle; } set { this.throttle = value; } } } class WrappedTransaction { Transaction transaction; internal WrappedTransaction(Transaction transaction) { this.transaction = transaction; } internal Transaction Transaction { get { return this.transaction; } } } } // 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
- SystemMulticastIPAddressInformation.cs
- WebBrowserUriTypeConverter.cs
- DbConnectionInternal.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- ItemsControlAutomationPeer.cs
- ViewRendering.cs
- PointHitTestResult.cs
- PolicyImporterElement.cs
- KeyedHashAlgorithm.cs
- SwitchElementsCollection.cs
- RootDesignerSerializerAttribute.cs
- ConfigXmlSignificantWhitespace.cs
- PersonalizationState.cs
- FlatButtonAppearance.cs
- JsonEnumDataContract.cs
- XmlCustomFormatter.cs
- WindowsToolbarItemAsMenuItem.cs
- SocketStream.cs
- BinaryObjectWriter.cs
- FocusTracker.cs
- DetailsViewUpdatedEventArgs.cs
- ProfileProvider.cs
- DataGridViewColumnTypeEditor.cs
- GuidConverter.cs
- DataGridPagingPage.cs
- PopupRoot.cs
- WriteFileContext.cs
- NameSpaceExtractor.cs
- CodeAttributeDeclarationCollection.cs
- ObfuscateAssemblyAttribute.cs
- ByteAnimation.cs
- RowType.cs
- BaseParagraph.cs
- _ListenerAsyncResult.cs
- StrongNamePublicKeyBlob.cs
- Constants.cs
- MergablePropertyAttribute.cs
- FixedSOMGroup.cs
- GridItem.cs
- TokenBasedSetEnumerator.cs
- SqlDesignerDataSourceView.cs
- Selector.cs
- CollectionsUtil.cs
- CompiledRegexRunner.cs
- ErrorFormatterPage.cs
- NetworkStream.cs
- HostProtectionPermission.cs
- IdentifierCollection.cs
- TableLayoutColumnStyleCollection.cs
- ColumnMapCopier.cs
- ObjectViewEntityCollectionData.cs
- OlePropertyStructs.cs
- WmlPanelAdapter.cs
- XmlElementAttributes.cs
- EDesignUtil.cs
- ControlPaint.cs
- CompoundFileDeflateTransform.cs
- SiteMapProvider.cs
- IssuedTokenClientCredential.cs
- RemotingException.cs
- StylusShape.cs
- HttpAsyncResult.cs
- ByteConverter.cs
- WriterOutput.cs
- _OSSOCK.cs
- XmlNodeReader.cs
- RightsManagementPermission.cs
- SqlPersistenceProviderFactory.cs
- GridViewRowEventArgs.cs
- DynamicDiscoSearcher.cs
- OleServicesContext.cs
- Main.cs
- regiisutil.cs
- AdPostCacheSubstitution.cs
- ClientBuildManagerTypeDescriptionProviderBridge.cs
- OleDragDropHandler.cs
- PackageRelationshipCollection.cs
- MatrixCamera.cs
- SQLBoolean.cs
- ListContractAdapter.cs
- DataFieldEditor.cs
- JoinCqlBlock.cs
- DataSourceXmlElementAttribute.cs
- HostExecutionContextManager.cs
- DataPager.cs
- SchemaSetCompiler.cs
- XmlSchemaElement.cs
- Hashtable.cs
- SecurityElement.cs
- TemplateAction.cs
- SecurityManager.cs
- ScaleTransform.cs
- VectorConverter.cs
- ProfilePropertySettingsCollection.cs
- MouseEventArgs.cs
- DateRangeEvent.cs
- MatrixTransform.cs
- EntityParameter.cs
- XmlEncodedRawTextWriter.cs
- SmtpNegotiateAuthenticationModule.cs