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
- FileNameEditor.cs
- Int16.cs
- DateTimeConverter.cs
- RuntimeConfigLKG.cs
- MimeAnyImporter.cs
- PropertySegmentSerializationProvider.cs
- LogicalExpr.cs
- WebPartCatalogCloseVerb.cs
- UInt64Converter.cs
- CodeLinePragma.cs
- Cursor.cs
- ColumnHeaderConverter.cs
- Pkcs7Recipient.cs
- EditorBrowsableAttribute.cs
- SoundPlayer.cs
- ProcessThread.cs
- AttachedPropertyBrowsableWhenAttributePresentAttribute.cs
- WindowsToolbarAsMenu.cs
- XmlMapping.cs
- HighlightVisual.cs
- TriggerAction.cs
- Single.cs
- StartUpEventArgs.cs
- Vector.cs
- ChtmlTextWriter.cs
- TemplateBindingExtension.cs
- BaseProcessProtocolHandler.cs
- ToolStripItemDataObject.cs
- DefaultSection.cs
- DialogWindow.cs
- CompilerCollection.cs
- CodeLinePragma.cs
- ControlUtil.cs
- EdmEntityTypeAttribute.cs
- Preprocessor.cs
- AttributeEmitter.cs
- RetriableClipboard.cs
- PropertyNames.cs
- CreateRefExpr.cs
- Gdiplus.cs
- Preprocessor.cs
- GridViewRowEventArgs.cs
- DataRowComparer.cs
- DoubleKeyFrameCollection.cs
- LoadedEvent.cs
- AbsoluteQuery.cs
- EncryptedHeader.cs
- RoleGroupCollection.cs
- ReadOnlyDataSource.cs
- VariantWrapper.cs
- TypeCollectionPropertyEditor.cs
- FixedDSBuilder.cs
- MediaPlayerState.cs
- SymmetricCryptoHandle.cs
- DesignerActionVerbItem.cs
- PathGeometry.cs
- DesignTimeVisibleAttribute.cs
- DiscriminatorMap.cs
- SqlWebEventProvider.cs
- DriveNotFoundException.cs
- PersonalizationState.cs
- DataBindingCollection.cs
- Property.cs
- BooleanToVisibilityConverter.cs
- GZipObjectSerializer.cs
- OdbcConnectionHandle.cs
- followingquery.cs
- AnnotationComponentChooser.cs
- PolicyChain.cs
- HttpListenerContext.cs
- UnorderedHashRepartitionStream.cs
- StylusPointProperties.cs
- GraphicsContext.cs
- Version.cs
- AttributeSetAction.cs
- TranslateTransform3D.cs
- DataGridViewColumnEventArgs.cs
- EdmSchemaError.cs
- BaseParagraph.cs
- EventSetterHandlerConverter.cs
- ComponentCommands.cs
- Mappings.cs
- _ConnectStream.cs
- TypeSystemProvider.cs
- ContentTypeSettingClientMessageFormatter.cs
- InitializingNewItemEventArgs.cs
- DiagnosticEventProvider.cs
- BindingEntityInfo.cs
- DataServiceOperationContext.cs
- CompilerErrorCollection.cs
- Misc.cs
- TextComposition.cs
- base64Transforms.cs
- UIPermission.cs
- ApplicationDirectoryMembershipCondition.cs
- XpsPackagingException.cs
- OciLobLocator.cs
- PageAdapter.cs
- ConnectionManagementElementCollection.cs
- PlanCompilerUtil.cs