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
- EncodingTable.cs
- Graph.cs
- SpotLight.cs
- XsdCachingReader.cs
- MultiViewDesigner.cs
- CmsInterop.cs
- InputLanguageCollection.cs
- ObjectParameter.cs
- TCPListener.cs
- PartialTrustHelpers.cs
- PolicyReader.cs
- SqlServer2KCompatibilityCheck.cs
- Track.cs
- ArgIterator.cs
- _SslStream.cs
- OutgoingWebResponseContext.cs
- SecureEnvironment.cs
- PerformanceCounterCategory.cs
- WindowsStatusBar.cs
- BevelBitmapEffect.cs
- XmlEntity.cs
- BadImageFormatException.cs
- MSAANativeProvider.cs
- LocalizationComments.cs
- EventArgs.cs
- QilFactory.cs
- XmlUtf8RawTextWriter.cs
- ContainerParagraph.cs
- NetCodeGroup.cs
- HttpWebRequestElement.cs
- PointUtil.cs
- ObjectDataSourceSelectingEventArgs.cs
- StoreItemCollection.Loader.cs
- Style.cs
- TaiwanLunisolarCalendar.cs
- KeyboardNavigation.cs
- HtmlMeta.cs
- PropertyPathWorker.cs
- PropertyMetadata.cs
- AssociatedControlConverter.cs
- CacheOutputQuery.cs
- MembershipUser.cs
- CheckBoxFlatAdapter.cs
- PtsPage.cs
- ToolStripDropDownClosingEventArgs.cs
- HostingEnvironmentException.cs
- PointF.cs
- CodeDomConfigurationHandler.cs
- AggregationMinMaxHelpers.cs
- WpfMemberInvoker.cs
- DataControlExtensions.cs
- QuaternionAnimation.cs
- AcceleratedTokenAuthenticator.cs
- ACL.cs
- MSAAWinEventWrap.cs
- ContravarianceAdapter.cs
- ScriptControl.cs
- MessagePropertyVariants.cs
- TextTreeNode.cs
- ComplexTypeEmitter.cs
- DataGridSortCommandEventArgs.cs
- ActivityMarkupSerializer.cs
- NameObjectCollectionBase.cs
- Subtree.cs
- TileBrush.cs
- PenCursorManager.cs
- OleDbPropertySetGuid.cs
- WinEventHandler.cs
- DragCompletedEventArgs.cs
- MouseCaptureWithinProperty.cs
- SqlUdtInfo.cs
- MultiPartWriter.cs
- HandledEventArgs.cs
- CompensatableTransactionScopeActivityDesigner.cs
- AutoGeneratedField.cs
- DeploymentExceptionMapper.cs
- ConfigurationSchemaErrors.cs
- EntityDataSourceDesigner.cs
- SystemDropShadowChrome.cs
- CodeAssignStatement.cs
- DataTemplateSelector.cs
- ListenerElementsCollection.cs
- TypeSystem.cs
- HwndProxyElementProvider.cs
- InputProcessorProfiles.cs
- RelationshipType.cs
- ResourcesBuildProvider.cs
- LineSegment.cs
- HtmlInputCheckBox.cs
- AstTree.cs
- LogEntrySerializer.cs
- RightsDocument.cs
- HtmlHead.cs
- StylusEditingBehavior.cs
- HtmlTable.cs
- PageContentAsyncResult.cs
- AsnEncodedData.cs
- UInt16Converter.cs
- LayoutExceptionEventArgs.cs
- CodeAssignStatement.cs