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
- GridSplitter.cs
- SafeFileMappingHandle.cs
- SmtpReplyReaderFactory.cs
- VirtualPathUtility.cs
- TableAdapterManagerNameHandler.cs
- ExceptionUtility.cs
- ToolStripGrip.cs
- ReceiveErrorHandling.cs
- CalendarAutoFormat.cs
- SamlAttribute.cs
- GeometryDrawing.cs
- JsonQNameDataContract.cs
- LicenseProviderAttribute.cs
- ObjectListSelectEventArgs.cs
- InstanceOwnerException.cs
- XmlSchemaExternal.cs
- ServiceNameCollection.cs
- ScriptDescriptor.cs
- SchemaName.cs
- MouseActionValueSerializer.cs
- BamlResourceContent.cs
- ExtendedPropertyCollection.cs
- DropShadowBitmapEffect.cs
- ConfigurationLockCollection.cs
- NameTable.cs
- DetailsViewDeletedEventArgs.cs
- ObjectListCommand.cs
- DBSqlParserTable.cs
- FramingDecoders.cs
- OutputScopeManager.cs
- NavigatorInvalidBodyAccessException.cs
- TransactionTable.cs
- METAHEADER.cs
- NavigationPropertyEmitter.cs
- ThicknessKeyFrameCollection.cs
- IdentifierCreationService.cs
- BamlTreeUpdater.cs
- StreamHelper.cs
- MessageSecurityOverTcp.cs
- TimeoutValidationAttribute.cs
- DataSourceBooleanViewSchemaConverter.cs
- externdll.cs
- BaseHashHelper.cs
- FormViewDeletedEventArgs.cs
- LocatorPartList.cs
- Point4D.cs
- Crc32Helper.cs
- QueryExpression.cs
- EtwTrackingParticipant.cs
- ConnectionStringsExpressionBuilder.cs
- StructuredCompositeActivityDesigner.cs
- MsmqIntegrationValidationBehavior.cs
- ProfileGroupSettingsCollection.cs
- PingOptions.cs
- WindowsButton.cs
- ExternalFile.cs
- DurableRuntimeValidator.cs
- ActivityTypeDesigner.xaml.cs
- UInt32Storage.cs
- DataGridViewCellStyleEditor.cs
- DataTemplateKey.cs
- FlatButtonAppearance.cs
- MsmqNonTransactedPoisonHandler.cs
- DateTimePicker.cs
- XmlQualifiedName.cs
- SoapAttributes.cs
- TypefaceMap.cs
- SqlOuterApplyReducer.cs
- DataFormats.cs
- MapPathBasedVirtualPathProvider.cs
- StrongNameUtility.cs
- FormattedTextSymbols.cs
- HtmlInputImage.cs
- BindingContext.cs
- Token.cs
- IndependentAnimationStorage.cs
- ConnectionStringSettings.cs
- TranslateTransform.cs
- PersonalizationProviderCollection.cs
- BaseTemplateParser.cs
- ZipIOExtraField.cs
- ConfigXmlText.cs
- EntityRecordInfo.cs
- MenuAdapter.cs
- Console.cs
- SqlPersonalizationProvider.cs
- DashStyle.cs
- ExtentCqlBlock.cs
- RecognizeCompletedEventArgs.cs
- BitmapSizeOptions.cs
- ParameterBuilder.cs
- RemoteWebConfigurationHostStream.cs
- AuthenticationModulesSection.cs
- File.cs
- GroupItem.cs
- ComplexPropertyEntry.cs
- HttpRequest.cs
- WSSecurityOneDotOneSendSecurityHeader.cs
- WebPartTransformer.cs
- XmlTextEncoder.cs