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
- RawKeyboardInputReport.cs
- ReferentialConstraintRoleElement.cs
- ConfigXmlText.cs
- FontFamily.cs
- CompositeScriptReference.cs
- ItemCheckEvent.cs
- ListenerUnsafeNativeMethods.cs
- TextProperties.cs
- BaseDataBoundControl.cs
- XPathDocumentNavigator.cs
- TreeNodeBindingCollection.cs
- AppSettingsSection.cs
- ExpressionConverter.cs
- TargetControlTypeAttribute.cs
- MulticastDelegate.cs
- ErrorHandler.cs
- SqlWebEventProvider.cs
- DependencyObjectType.cs
- ArrayList.cs
- log.cs
- HttpCacheParams.cs
- CodeExpressionStatement.cs
- DataListItem.cs
- CompiledXpathExpr.cs
- NativeWindow.cs
- Identity.cs
- XmlSchemaSimpleTypeUnion.cs
- SchemaMapping.cs
- DiscoveryRequestHandler.cs
- DataPointer.cs
- Preprocessor.cs
- ListViewItem.cs
- QueryCursorEventArgs.cs
- HttpStreamFormatter.cs
- PrintPreviewDialog.cs
- RelatedView.cs
- SplineKeyFrames.cs
- DataGridViewLinkCell.cs
- hwndwrapper.cs
- SafeHandle.cs
- WinFormsComponentEditor.cs
- FontDialog.cs
- SelectionListComponentEditor.cs
- DockPattern.cs
- __FastResourceComparer.cs
- CharacterBuffer.cs
- DbException.cs
- CustomLineCap.cs
- RSAOAEPKeyExchangeDeformatter.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- PrintEvent.cs
- HtmlValidationSummaryAdapter.cs
- TextSpanModifier.cs
- PropertyInformation.cs
- SiteMapNodeItemEventArgs.cs
- SafeArrayTypeMismatchException.cs
- webproxy.cs
- ProcessModelInfo.cs
- EntityClientCacheEntry.cs
- ReachVisualSerializerAsync.cs
- ReadOnlyHierarchicalDataSourceView.cs
- SiteMapNodeCollection.cs
- VerificationException.cs
- Completion.cs
- EventLogPermissionAttribute.cs
- CredentialCache.cs
- LinearGradientBrush.cs
- ReferentialConstraint.cs
- BitConverter.cs
- RichTextBoxContextMenu.cs
- StringValueSerializer.cs
- UseLicense.cs
- TreeNodeEventArgs.cs
- MessageQueueAccessControlEntry.cs
- SevenBitStream.cs
- BitVector32.cs
- Model3D.cs
- ColumnCollection.cs
- NativeMethods.cs
- EdgeProfileValidation.cs
- ApplicationInterop.cs
- UdpMessageProperty.cs
- UnsafeNativeMethods.cs
- WorkItem.cs
- GPRECTF.cs
- LinqDataSourceValidationException.cs
- Vector3DCollectionConverter.cs
- CommandID.cs
- PackagePart.cs
- FileLogRecordHeader.cs
- AssertFilter.cs
- Point3DAnimation.cs
- AggregateNode.cs
- ManifestBasedResourceGroveler.cs
- XmlMessageFormatter.cs
- ExpandCollapsePattern.cs
- PropertyValueChangedEvent.cs
- StandardOleMarshalObject.cs
- TextRunTypographyProperties.cs
- UnsafeNativeMethodsPenimc.cs