Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / ConnectionAcceptor.cs / 1 / ConnectionAcceptor.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Diagnostics; using System.ServiceModel; using System.ServiceModel.Diagnostics; using System.ServiceModel.Dispatcher; using System.Threading; delegate void ConnectionAvailableCallback(IConnection connection, ItemDequeuedCallback connectionDequeuedCallback); delegate void ErrorCallback(Exception exception); class ConnectionAcceptor : IDisposable { int maxAccepts; int maxPendingConnections; int connections; int pendingAccepts; IConnectionListener listener; AsyncCallback acceptCompletedCallback; WaitCallback scheduleAcceptCallback; ItemDequeuedCallback onConnectionDequeued; bool isDisposed; ConnectionAvailableCallback callback; ErrorCallback errorCallback; public ConnectionAcceptor(IConnectionListener listener, int maxAccepts, int maxPendingConnections, ConnectionAvailableCallback callback) : this(listener, maxAccepts, maxPendingConnections, callback, null) { // empty } public ConnectionAcceptor(IConnectionListener listener, int maxAccepts, int maxPendingConnections, ConnectionAvailableCallback callback, ErrorCallback errorCallback) { if (maxAccepts <= 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxAccepts", maxAccepts, SR.GetString(SR.ValueMustBePositive))); } DiagnosticUtility.DebugAssert(maxPendingConnections > 0, "maxPendingConnections must be positive"); this.listener = listener; this.maxAccepts = maxAccepts; this.maxPendingConnections = maxPendingConnections; this.callback = callback; this.errorCallback = errorCallback; this.onConnectionDequeued = new ItemDequeuedCallback(OnConnectionDequeued); this.acceptCompletedCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(AcceptCompletedCallback)); this.scheduleAcceptCallback = new WaitCallback(ScheduleAcceptCallback); } bool IsAcceptNecessary { get { return (pendingAccepts < maxAccepts) && ((connections + pendingAccepts) < maxPendingConnections) && !isDisposed; } } public int ConnectionCount { get { return connections; } } object ThisLock { get { return this; } } void AcceptIfNecessary(bool startAccepting) { if (IsAcceptNecessary) { lock (ThisLock) { while (IsAcceptNecessary) { IAsyncResult result = null; Exception unexpectedException = null; try { result = listener.BeginAccept(acceptCompletedCallback, null); } catch (CommunicationException exception) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information); } } catch (Exception exception) { if (DiagnosticUtility.IsFatal(exception)) { throw; } if (startAccepting) { // Since we're under a call to StartAccepting(), just throw the exception up the stack. throw; } if ((errorCallback == null) && !ExceptionHandler.HandleTransportExceptionHelper(exception)) { throw; } unexpectedException = exception; } if ((unexpectedException != null) && (errorCallback != null)) { errorCallback(unexpectedException); } if (result != null) { // don't block our accept processing loop if (result.CompletedSynchronously) { IOThreadScheduler.ScheduleCallback(scheduleAcceptCallback, result); } pendingAccepts++; } } } } } void AcceptCompletedCallback(IAsyncResult result) { if (result.CompletedSynchronously) { return; } HandleCompletedAccept(result); } public void Dispose() { lock (ThisLock) { if (!isDisposed) { isDisposed = true; listener.Dispose(); } } } void HandleCompletedAccept(IAsyncResult result) { IConnection connection = null; lock (ThisLock) { bool success = false; Exception unexpectedException = null; try { if (!isDisposed) { connection = listener.EndAccept(result); if (connection != null) { if (DiagnosticUtility.ShouldTraceWarning) { if (connections + 1 >= maxPendingConnections) { TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.MaxPendingConnectionsReached, new StringTraceRecord("MaxPendingConnections", maxPendingConnections.ToString(System.Globalization.CultureInfo.InvariantCulture)), this, null); } } // This is incremented after the Trace just in case the Trace throws. connections++; } } success = true; } catch (CommunicationException exception) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information); } } catch (Exception exception) { if (DiagnosticUtility.IsFatal(exception)) { throw; } if ((errorCallback == null) && !ExceptionHandler.HandleTransportExceptionHelper(exception)) { throw; } unexpectedException = exception; } finally { if (!success) { connection = null; } pendingAccepts--; } if ((unexpectedException != null) && (errorCallback != null)) { errorCallback(unexpectedException); } } AcceptIfNecessary(false); if (connection != null) { callback(connection, onConnectionDequeued); } } void OnConnectionDequeued() { lock (ThisLock) { connections--; } AcceptIfNecessary(false); } void ScheduleAcceptCallback(object state) { HandleCompletedAccept((IAsyncResult)state); } public void StartAccepting() { listener.Listen(); AcceptIfNecessary(true); } } } // 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
- Simplifier.cs
- TextModifier.cs
- DataSourceDesigner.cs
- DbDataReader.cs
- NativeMethods.cs
- TempFiles.cs
- GorillaCodec.cs
- XamlHostingConfiguration.cs
- XamlWriterExtensions.cs
- JsonServiceDocumentSerializer.cs
- WebPartCollection.cs
- PropVariant.cs
- HtmlControlDesigner.cs
- DriveNotFoundException.cs
- SelectionItemProviderWrapper.cs
- PipelineModuleStepContainer.cs
- AnnotationHighlightLayer.cs
- PluralizationService.cs
- MulticastIPAddressInformationCollection.cs
- ImportedNamespaceContextItem.cs
- NameValueFileSectionHandler.cs
- BitmapDecoder.cs
- SubMenuStyleCollection.cs
- XmlHelper.cs
- SizeFConverter.cs
- _FixedSizeReader.cs
- TdsParserHelperClasses.cs
- DBParameter.cs
- WinFormsSpinner.cs
- CheckBox.cs
- VectorConverter.cs
- SyndicationElementExtension.cs
- SystemKeyConverter.cs
- FormsAuthenticationModule.cs
- ReadingWritingEntityEventArgs.cs
- ArcSegment.cs
- OracleEncoding.cs
- GenericEnumerator.cs
- SimpleWebHandlerParser.cs
- RadioButtonList.cs
- TextContainer.cs
- HybridWebProxyFinder.cs
- WindowsPen.cs
- UnsettableComboBox.cs
- HtmlShim.cs
- ReflectionHelper.cs
- CommonProperties.cs
- SapiRecoContext.cs
- GlobalizationSection.cs
- AlternateView.cs
- ToolStripDropDownMenu.cs
- FullTextLine.cs
- Panel.cs
- ToggleProviderWrapper.cs
- ComponentDispatcherThread.cs
- DataGridViewRowHeaderCell.cs
- Tablet.cs
- ServiceDeploymentInfo.cs
- Operand.cs
- GridSplitterAutomationPeer.cs
- HttpResponseHeader.cs
- PrintPreviewGraphics.cs
- MetadataCacheItem.cs
- VersionedStream.cs
- BinaryCommonClasses.cs
- TreeNode.cs
- ColumnMapProcessor.cs
- CheckBoxField.cs
- FieldNameLookup.cs
- PageAsyncTaskManager.cs
- UserNameSecurityTokenParameters.cs
- RTLAwareMessageBox.cs
- TiffBitmapEncoder.cs
- NonParentingControl.cs
- webclient.cs
- FieldMetadata.cs
- NavigationWindowAutomationPeer.cs
- odbcmetadatacolumnnames.cs
- DataGridViewComboBoxColumn.cs
- MsmqAppDomainProtocolHandler.cs
- RemoteDebugger.cs
- TransactedReceiveScope.cs
- ProxyElement.cs
- IndentedTextWriter.cs
- OdbcUtils.cs
- PersonalizationStateQuery.cs
- AlignmentYValidation.cs
- UniformGrid.cs
- XmlAttributeOverrides.cs
- XPathDocumentNavigator.cs
- IdentityModelDictionary.cs
- TreeViewItemAutomationPeer.cs
- WebPermission.cs
- XmlSchemaAttribute.cs
- ToolStripControlHost.cs
- InputProcessorProfilesLoader.cs
- XmlObjectSerializerWriteContextComplex.cs
- EventProviderTraceListener.cs
- StrokeCollection.cs
- CallTemplateAction.cs