Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / ConnectionDemuxer.cs / 1 / ConnectionDemuxer.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Diagnostics; using System.ServiceModel; using System.ServiceModel.Activation; using System.ServiceModel.Dispatcher; using System.IO; using System.Threading; using System.Collections.Generic; using System.Globalization; using System.ServiceModel.Diagnostics; sealed class ConnectionDemuxer : IDisposable { ConnectionAcceptor acceptor; // we use this list to track readers that don't have a clear owner (so they don't get GC'ed) ListconnectionReaders; bool isDisposed; ConnectionModeCallback onConnectionModeKnown; ConnectionModeCallback onCachedConnectionModeKnown; ConnectionClosedCallback onConnectionClosed; ServerSessionPreambleCallback onSessionPreambleKnown; ServerSingletonPreambleCallback onSingletonPreambleKnown; WaitCallback reuseConnectionCallback; ServerSessionPreambleDemuxCallback serverSessionPreambleCallback; SingletonPreambleDemuxCallback singletonPreambleCallback; TransportSettingsCallback transportSettingsCallback; ItemDequeuedCallback pooledConnectionDequeuedCallback; OnViaDelegate viaDelegate; TimeSpan channelInitializationTimeout; TimeSpan idleTimeout; int maxPooledConnections; int pooledConnectionCount; public ConnectionDemuxer(IConnectionListener listener, int maxAccepts, int maxPendingConnections, TimeSpan channelInitializationTimeout, TimeSpan idleTimeout, int maxPooledConnections, TransportSettingsCallback transportSettingsCallback, SingletonPreambleDemuxCallback singletonPreambleCallback, ServerSessionPreambleDemuxCallback serverSessionPreambleCallback, ErrorCallback errorCallback) { this.connectionReaders = new List (); this.acceptor = new ConnectionAcceptor(listener, maxAccepts, maxPendingConnections, OnConnectionAvailable, errorCallback); this.channelInitializationTimeout = channelInitializationTimeout; this.idleTimeout = idleTimeout; this.maxPooledConnections = maxPooledConnections; this.onConnectionClosed = new ConnectionClosedCallback(OnConnectionClosed); this.transportSettingsCallback = transportSettingsCallback; this.singletonPreambleCallback = singletonPreambleCallback; this.serverSessionPreambleCallback = serverSessionPreambleCallback; } object ThisLock { get { return this; } } public void Dispose() { lock (ThisLock) { if (isDisposed) return; isDisposed = true; } for (int i = 0; i < connectionReaders.Count; i++) { connectionReaders[i].Dispose(); } connectionReaders.Clear(); acceptor.Dispose(); } ConnectionModeReader SetupModeReader(IConnection connection, bool isCached) { ConnectionModeReader modeReader; if (isCached) { if (onCachedConnectionModeKnown == null) { onCachedConnectionModeKnown = new ConnectionModeCallback(OnCachedConnectionModeKnown); } modeReader = new ConnectionModeReader(connection, onCachedConnectionModeKnown, onConnectionClosed); } else { if (onConnectionModeKnown == null) { onConnectionModeKnown = new ConnectionModeCallback(OnConnectionModeKnown); } modeReader = new ConnectionModeReader(connection, onConnectionModeKnown, onConnectionClosed); } lock (ThisLock) { if (isDisposed) { modeReader.Dispose(); return null; } connectionReaders.Add(modeReader); return modeReader; } } public void ReuseConnection(IConnection connection, TimeSpan closeTimeout) { connection.ExceptionEventType = TraceEventType.Information; ConnectionModeReader modeReader = SetupModeReader(connection, true); if (modeReader != null) { if (reuseConnectionCallback == null) { reuseConnectionCallback = new WaitCallback(ReuseConnectionCallback); } IOThreadScheduler.ScheduleCallback(reuseConnectionCallback, new ReuseConnectionState(modeReader, closeTimeout)); } } void ReuseConnectionCallback(object state) { ReuseConnectionState connectionState = (ReuseConnectionState)state; bool closeReader = false; lock (ThisLock) { if (this.pooledConnectionCount >= this.maxPooledConnections) { closeReader = true; } else { this.pooledConnectionCount++; } } if (closeReader) { if (DiagnosticUtility.ShouldTraceWarning) { DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning, TraceCode.ServerMaxPooledConnectionsQuotaReached, SR.GetString(SR.TraceCodeServerMaxPooledConnectionsQuotaReached, maxPooledConnections), new StringTraceRecord("MaxOutboundConnectionsPerEndpoint", maxPooledConnections.ToString(CultureInfo.InvariantCulture)), null, this); } connectionState.ModeReader.CloseFromPool(connectionState.CloseTimeout); } else { if (this.pooledConnectionDequeuedCallback == null) { this.pooledConnectionDequeuedCallback = new ItemDequeuedCallback(PooledConnectionDequeuedCallback); } connectionState.ModeReader.StartReading(this.idleTimeout, this.pooledConnectionDequeuedCallback); } } void PooledConnectionDequeuedCallback() { lock (ThisLock) { this.pooledConnectionCount--; DiagnosticUtility.DebugAssert(this.pooledConnectionCount >= 0, "Connection Throttle should never be negative"); } } void OnConnectionAvailable(IConnection connection, ItemDequeuedCallback connectionDequeuedCallback) { ConnectionModeReader modeReader = SetupModeReader(connection, false); if (modeReader != null) { // StartReading() will never throw non-fatal exceptions; // it propagates all exceptions into the onConnectionModeKnown callback, // which is where we need our robust handling modeReader.StartReading(this.channelInitializationTimeout, connectionDequeuedCallback); } else { connectionDequeuedCallback(); } } void OnCachedConnectionModeKnown(ConnectionModeReader modeReader) { OnConnectionModeKnownCore(modeReader, true); } void OnConnectionModeKnown(ConnectionModeReader modeReader) { OnConnectionModeKnownCore(modeReader, false); } void OnConnectionModeKnownCore(ConnectionModeReader modeReader, bool isCached) { lock (ThisLock) { if (isDisposed) return; this.connectionReaders.Remove(modeReader); } bool closeReader = true; try { FramingMode framingMode; try { framingMode = modeReader.GetConnectionMode(); } catch (CommunicationException exception) { TraceEventType eventType = modeReader.Connection.ExceptionEventType; if (DiagnosticUtility.ShouldTrace(eventType)) { DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, eventType); } return; } catch (TimeoutException exception) { if (!isCached) { exception = new TimeoutException(SR.GetString(SR.ChannelInitializationTimeout, this.channelInitializationTimeout), exception); System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(exception); } TraceEventType eventType = modeReader.Connection.ExceptionEventType; if (DiagnosticUtility.ShouldTrace(eventType)) { DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, eventType); } return; } switch (framingMode) { case FramingMode.Duplex: OnDuplexConnection(modeReader.Connection, modeReader.ConnectionDequeuedCallback, modeReader.StreamPosition, modeReader.BufferOffset, modeReader.BufferSize, modeReader.GetRemainingTimeout()); break; case FramingMode.Singleton: OnSingletonConnection(modeReader.Connection, modeReader.ConnectionDequeuedCallback, modeReader.StreamPosition, modeReader.BufferOffset, modeReader.BufferSize, modeReader.GetRemainingTimeout()); break; default: { Exception inner = new InvalidDataException(SR.GetString( SR.FramingModeNotSupported, framingMode)); Exception exception = new ProtocolException(inner.Message, inner); FramingEncodingString.AddFaultString(exception, FramingEncodingString.UnsupportedModeFault); System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(exception); return; } } closeReader = false; } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } if (!ExceptionHandler.HandleTransportExceptionHelper(e)) { throw; } // containment -- the reader is aborted, no need for additional containment } finally { if (closeReader) { modeReader.Dispose(); } } } void OnConnectionClosed(InitialServerConnectionReader connectionReader) { lock (ThisLock) { if (isDisposed) return; connectionReaders.Remove(connectionReader); } } void OnSingletonConnection(IConnection connection, ItemDequeuedCallback connectionDequeuedCallback, long streamPosition, int offset, int size, TimeSpan timeout) { if (onSingletonPreambleKnown == null) { onSingletonPreambleKnown = OnSingletonPreambleKnown; } ServerSingletonPreambleConnectionReader singletonPreambleReader = new ServerSingletonPreambleConnectionReader(connection, connectionDequeuedCallback, streamPosition, offset, size, transportSettingsCallback, onConnectionClosed, onSingletonPreambleKnown); lock (ThisLock) { if (isDisposed) { singletonPreambleReader.Dispose(); return; } connectionReaders.Add(singletonPreambleReader); } singletonPreambleReader.StartReading(viaDelegate, timeout); } void OnSingletonPreambleKnown(ServerSingletonPreambleConnectionReader serverSingletonPreambleReader) { lock (ThisLock) { if (isDisposed) { return; } connectionReaders.Remove(serverSingletonPreambleReader); } ISingletonChannelListener singletonChannelListener = singletonPreambleCallback(serverSingletonPreambleReader); DiagnosticUtility.DebugAssert(singletonChannelListener != null, "singletonPreambleCallback must return a listener or send a Fault/throw"); // transfer ownership of the connection from the preamble reader to the message handler TimeoutHelper timeoutHelper = new TimeoutHelper(singletonChannelListener.ReceiveTimeout); IConnection upgradedConnection = serverSingletonPreambleReader.CompletePreamble(timeoutHelper.RemainingTime()); ServerSingletonConnectionReader singletonReader = new ServerSingletonConnectionReader(serverSingletonPreambleReader, upgradedConnection, this); RequestContext requestContext = singletonReader.ReceiveRequest(timeoutHelper.RemainingTime()); singletonChannelListener.ReceiveRequest(requestContext, serverSingletonPreambleReader.ConnectionDequeuedCallback, true); } void OnSessionPreambleKnown(ServerSessionPreambleConnectionReader serverSessionPreambleReader) { lock (ThisLock) { if (isDisposed) { return; } connectionReaders.Remove(serverSessionPreambleReader); } serverSessionPreambleCallback(serverSessionPreambleReader, this); } void OnDuplexConnection(IConnection connection, ItemDequeuedCallback connectionDequeuedCallback, long streamPosition, int offset, int size, TimeSpan timeout) { if (onSessionPreambleKnown == null) { onSessionPreambleKnown = OnSessionPreambleKnown; } ServerSessionPreambleConnectionReader sessionPreambleReader = new ServerSessionPreambleConnectionReader( connection, connectionDequeuedCallback, streamPosition, offset, size, transportSettingsCallback, onConnectionClosed, onSessionPreambleKnown); lock (ThisLock) { if (isDisposed) { sessionPreambleReader.Dispose(); return; } connectionReaders.Add(sessionPreambleReader); } sessionPreambleReader.StartReading(viaDelegate, timeout); } public void StartDemuxing() { StartDemuxing(null); } public void StartDemuxing(OnViaDelegate viaDelegate) { this.viaDelegate = viaDelegate; acceptor.StartAccepting(); } class ReuseConnectionState { ConnectionModeReader modeReader; TimeSpan closeTimeout; public ReuseConnectionState(ConnectionModeReader modeReader, TimeSpan closeTimeout) { this.modeReader = modeReader; this.closeTimeout = closeTimeout; } public ConnectionModeReader ModeReader { get { return this.modeReader; } } public TimeSpan CloseTimeout { get { return this.closeTimeout; } } } } } // 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
- MaterialGroup.cs
- CodeTypeParameter.cs
- XmlSerializerNamespaces.cs
- LOSFormatter.cs
- TextFindEngine.cs
- FlowDocumentPaginator.cs
- TableRowGroup.cs
- NonSerializedAttribute.cs
- Base64Encoder.cs
- LambdaCompiler.Generated.cs
- XmlSchemaObject.cs
- CuspData.cs
- ClientEventManager.cs
- DetailsViewAutoFormat.cs
- FixedSOMElement.cs
- ComponentGuaranteesAttribute.cs
- InternalSafeNativeMethods.cs
- CorruptingExceptionCommon.cs
- Model3DGroup.cs
- SelectedDatesCollection.cs
- ExpressionList.cs
- ParameterCollection.cs
- DynamicUpdateCommand.cs
- SR.cs
- SecurityCriticalDataForSet.cs
- DataGridViewRowHeightInfoPushedEventArgs.cs
- HtmlInputSubmit.cs
- GenericFlowSwitchHelper.cs
- ToolStripSeparatorRenderEventArgs.cs
- AdCreatedEventArgs.cs
- EndOfStreamException.cs
- DelayedRegex.cs
- PeerIPHelper.cs
- Image.cs
- CacheChildrenQuery.cs
- DependentList.cs
- glyphs.cs
- DataGridPagerStyle.cs
- TransactionChannelFaultConverter.cs
- Sql8ExpressionRewriter.cs
- ErrorHandlingAcceptor.cs
- FileDialogCustomPlacesCollection.cs
- TagNameToTypeMapper.cs
- DesignerActionPropertyItem.cs
- GlobalEventManager.cs
- Rotation3DAnimation.cs
- CacheEntry.cs
- DbParameterHelper.cs
- MasterPageBuildProvider.cs
- AutomationPatternInfo.cs
- UInt16Storage.cs
- EntitySetRetriever.cs
- DiscoveryDocumentReference.cs
- ObjectDataSourceSelectingEventArgs.cs
- CodeParameterDeclarationExpressionCollection.cs
- ListDictionary.cs
- CodeCommentStatementCollection.cs
- TextEditorTables.cs
- StylusPointPropertyInfoDefaults.cs
- StandardOleMarshalObject.cs
- DbParameterCollection.cs
- XmlSchemaCollection.cs
- HashLookup.cs
- ElapsedEventArgs.cs
- HttpContextBase.cs
- HtmlInputFile.cs
- VarInfo.cs
- WebBrowserPermission.cs
- GridItemPattern.cs
- XmlTextReaderImpl.cs
- altserialization.cs
- Root.cs
- JsonWriterDelegator.cs
- SecurityListenerSettingsLifetimeManager.cs
- GridEntryCollection.cs
- LinearQuaternionKeyFrame.cs
- DockingAttribute.cs
- PlanCompilerUtil.cs
- XmlKeywords.cs
- ActivityValidationServices.cs
- QueueException.cs
- future.cs
- TypeListConverter.cs
- CachedPathData.cs
- EventNotify.cs
- DataGridCaption.cs
- EncodingTable.cs
- TextElementEnumerator.cs
- BaseTemplateParser.cs
- TransportListener.cs
- RemotingAttributes.cs
- Attributes.cs
- TailCallAnalyzer.cs
- PageCodeDomTreeGenerator.cs
- Double.cs
- HttpHostedTransportConfiguration.cs
- NameValuePermission.cs
- CodeTypeMemberCollection.cs
- OpCopier.cs
- ListViewGroupItemCollection.cs