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
- IntegerValidatorAttribute.cs
- FilteredAttributeCollection.cs
- MD5.cs
- BindingNavigator.cs
- HostingPreferredMapPath.cs
- DrawingState.cs
- HotSpotCollection.cs
- IgnoreSection.cs
- ValidationEventArgs.cs
- SqlCommand.cs
- WmlPhoneCallAdapter.cs
- FigureParaClient.cs
- DispatcherSynchronizationContext.cs
- RawTextInputReport.cs
- EventProviderWriter.cs
- BinaryExpressionHelper.cs
- Relationship.cs
- cookieexception.cs
- ArithmeticException.cs
- ArgumentOutOfRangeException.cs
- RowUpdatingEventArgs.cs
- DBCommandBuilder.cs
- Color.cs
- ActivityDesignerLayoutSerializers.cs
- ComPlusContractBehavior.cs
- BoundPropertyEntry.cs
- XmlSchemaObjectTable.cs
- KeyValueInternalCollection.cs
- DataSourceXmlElementAttribute.cs
- _NetworkingPerfCounters.cs
- Highlights.cs
- ReadOnlyAttribute.cs
- ConfigurationSectionHelper.cs
- CategoryAttribute.cs
- CodeAttributeArgumentCollection.cs
- unitconverter.cs
- MultipleCopiesCollection.cs
- ResourceAttributes.cs
- ChannelSinkStacks.cs
- TriState.cs
- DataGridRowEventArgs.cs
- DoubleStorage.cs
- RankException.cs
- FilterableAttribute.cs
- CallSiteHelpers.cs
- PageThemeCodeDomTreeGenerator.cs
- LocatorPart.cs
- TraversalRequest.cs
- WindowsListViewGroupHelper.cs
- ModelChangedEventArgsImpl.cs
- BypassElementCollection.cs
- shaperfactoryquerycachekey.cs
- HwndProxyElementProvider.cs
- Slider.cs
- DragStartedEventArgs.cs
- EncoderExceptionFallback.cs
- KnownTypesHelper.cs
- formatter.cs
- MessageDesigner.cs
- PresentationTraceSources.cs
- TextTreeRootNode.cs
- SafeMarshalContext.cs
- UIElement3D.cs
- IdleTimeoutMonitor.cs
- StatementContext.cs
- QueryCursorEventArgs.cs
- ISFTagAndGuidCache.cs
- ProfileService.cs
- EntityDataSourceQueryBuilder.cs
- ZipIOCentralDirectoryFileHeader.cs
- DataListItem.cs
- ColorAnimationUsingKeyFrames.cs
- StoreAnnotationsMap.cs
- HealthMonitoringSectionHelper.cs
- FileSecurity.cs
- LostFocusEventManager.cs
- WeakEventTable.cs
- StorageComplexPropertyMapping.cs
- MailSettingsSection.cs
- DesignerPainter.cs
- XamlPointCollectionSerializer.cs
- DbgUtil.cs
- HMACSHA384.cs
- BamlRecords.cs
- SafeEventHandle.cs
- DrawListViewColumnHeaderEventArgs.cs
- MarkupWriter.cs
- PenCursorManager.cs
- SmiConnection.cs
- OptimalBreakSession.cs
- RemoveStoryboard.cs
- Thread.cs
- Gdiplus.cs
- SQLMoney.cs
- InvokeFunc.cs
- HttpConfigurationContext.cs
- HtmlInputPassword.cs
- WsdlServiceChannelBuilder.cs
- ActivityContext.cs
- EmptyEnumerator.cs