Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Remoting / Channels / CORE / SocketCache.cs / 1305376 / SocketCache.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //========================================================================== // File: SocketCache.cs // // Summary: Cache for client sockets. // //========================================================================= using System; using System.Collections; using System.Net; using System.Net.Sockets; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Threading; namespace System.Runtime.Remoting.Channels { // Delegate to method that will fabricate the appropriate socket handler internal delegate SocketHandler SocketHandlerFactory(Socket socket, SocketCache socketCache, String machineAndPort); // Used to cache client connections to a single port on a server internal class RemoteConnection { private static char[] colonSep = new char[]{':'}; private CachedSocketList _cachedSocketList; // reference back to the socket cache private SocketCache _socketCache; // remote endpoint data private String _machineAndPort; private IPAddress[] _addressList; private int _port; private EndPoint _lkgIPEndPoint; private bool connectIPv6 = false; private Uri _uri; internal RemoteConnection(SocketCache socketCache, String machineAndPort) { _socketCache = socketCache; _cachedSocketList = new CachedSocketList(socketCache.SocketTimeout, socketCache.CachePolicy); // parse "machinename:port", add a dummy scheme to get uri parsing _uri = new Uri("dummy://" + machineAndPort); _port = _uri.Port; _machineAndPort = machineAndPort; } // RemoteConnection internal SocketHandler GetSocket() { // try the cached socket list SocketHandler socketHandler = _cachedSocketList.GetSocket(); if (socketHandler != null) return socketHandler; // Otherwise, we'll just create a new one. return CreateNewSocket(); } // GetSocket internal void ReleaseSocket(SocketHandler socket) { socket.ReleaseControl(); _cachedSocketList.ReturnSocket(socket); } // ReleaseSocket private bool HasIPv6Address(IPAddress[] addressList) { foreach (IPAddress address in addressList) { if (address.AddressFamily == AddressFamily.InterNetworkV6) return true; } return false; } private void DisableNagleDelays(Socket socket) { // disable nagle delays socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1); } private SocketHandler CreateNewSocket() { // // We should not cache the DNS result // _addressList = Dns.GetHostAddresses(_uri.Host); connectIPv6 = Socket.OSSupportsIPv6 && HasIPv6Address(_addressList); // If there is only one entry in the list, just use that // we will fail if the connect on it fails if (_addressList.Length == 1) return CreateNewSocket(new IPEndPoint(_addressList[0], _port)); // If LKG is set try using that if (_lkgIPEndPoint != null) { try{ return CreateNewSocket(_lkgIPEndPoint); } catch (Exception) { // Since this fail null out LKG _lkgIPEndPoint = null; } } // If IPv6 is enabled try connecting to IP addresses if (connectIPv6) { try{ return CreateNewSocket(AddressFamily.InterNetworkV6); }catch (Exception) {} } // If everything fails try ipv4 addresses return CreateNewSocket(AddressFamily.InterNetwork); } private SocketHandler CreateNewSocket(EndPoint ipEndPoint) { Socket socket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); DisableNagleDelays(socket); InternalRemotingServices.RemotingTrace("RemoteConnection::CreateNewSocket: connecting new socket :: " + ipEndPoint); socket.Connect(ipEndPoint); _lkgIPEndPoint = socket.RemoteEndPoint; return _socketCache.CreateSocketHandler(socket, _machineAndPort); } // CreateNewSocket private SocketHandler CreateNewSocket(AddressFamily family) { Socket socket = new Socket(family, SocketType.Stream, ProtocolType.Tcp); DisableNagleDelays(socket); socket.Connect(_addressList, _port); _lkgIPEndPoint = socket.RemoteEndPoint; return _socketCache.CreateSocketHandler(socket, _machineAndPort); } // CreateNewSocket internal void TimeoutSockets(DateTime currentTime) { _cachedSocketList.TimeoutSockets(currentTime, _socketCache.SocketTimeout); } // TimeoutSockets } // class RemoteConnection internal class CachedSocket { private SocketHandler _socket; private DateTime _socketLastUsed; private CachedSocket _next; internal CachedSocket(SocketHandler socket, CachedSocket next) { _socket = socket; _socketLastUsed = DateTime.UtcNow; _next = next; } // CachedSocket internal SocketHandler Handler { get { return _socket; } } internal DateTime LastUsed { get { return _socketLastUsed; } } internal CachedSocket Next { get { return _next; } set { _next = value; } } } // class CachedSocket internal class CachedSocketList { private int _socketCount; private TimeSpan _socketLifetime; private SocketCachePolicy _socketCachePolicy; private CachedSocket _socketList; // linked list internal CachedSocketList(TimeSpan socketLifetime, SocketCachePolicy socketCachePolicy) { _socketCount = 0; _socketLifetime = socketLifetime; _socketCachePolicy = socketCachePolicy; _socketList = null; } // CachedSocketList internal SocketHandler GetSocket() { if (_socketCount == 0) return null; lock (this) { if (_socketList != null) { SocketHandler socket = _socketList.Handler; _socketList = _socketList.Next; bool bRes = socket.----ForControl(); // We should always have control since there shouldn't // be contention here. InternalRemotingServices.RemotingAssert(bRes, "someone else has the socket?"); _socketCount--; return socket; } } return null; } // GetSocket internal void ReturnSocket(SocketHandler socket) { TimeSpan socketActiveTime = DateTime.UtcNow - socket.CreationTime; bool closeSocket = false; lock (this) { // Check if socket active time has exceeded the lifetime // If it has just close the Socket if (_socketCachePolicy != SocketCachePolicy.AbsoluteTimeout || socketActiveTime < _socketLifetime) { // Ignore duplicate entries for the same socket handler for (CachedSocket curr = _socketList; curr != null; curr = curr.Next){ if (socket == curr.Handler) return; } _socketList = new CachedSocket(socket, _socketList); _socketCount++; } else { closeSocket = true; } } if(closeSocket) { socket.Close(); } } // ReturnSocket internal void TimeoutSockets(DateTime currentTime, TimeSpan socketLifetime) { lock (this) { CachedSocket prev = null; CachedSocket curr = _socketList; while (curr != null) { // see if it's lifetime has expired if ((_socketCachePolicy == SocketCachePolicy.AbsoluteTimeout && // This is for absolute (currentTime - curr.Handler.CreationTime) > socketLifetime) || (currentTime - curr.LastUsed) > socketLifetime) // This is relative behaviour { curr.Handler.Close(); // remove current cached socket from list if (prev == null) { // it's the first item, so update _socketList _socketList = curr.Next; curr = _socketList; } else { // remove current item from the list curr = curr.Next; prev.Next = curr; } // decrement socket count _socketCount--; } else { prev = curr; curr = curr.Next; } } } } // TimeoutSockets } // class CachedSocketList internal class SocketCache { // collection of RemoteConnection's. private static Hashtable _connections = new Hashtable(); private SocketHandlerFactory _handlerFactory; // socket timeout data private static RegisteredWaitHandle _registeredWaitHandle; private static WaitOrTimerCallback _socketTimeoutDelegate; private static AutoResetEvent _socketTimeoutWaitHandle; private static TimeSpan _socketTimeoutPollTime = TimeSpan.FromSeconds(10); private SocketCachePolicy _socketCachePolicy; private TimeSpan _socketTimeout; private int _receiveTimeout = 0; static SocketCache() { InitializeSocketTimeoutHandler(); } internal SocketCache(SocketHandlerFactory handlerFactory, SocketCachePolicy socketCachePolicy, TimeSpan socketTimeout) { _handlerFactory = handlerFactory; _socketCachePolicy = socketCachePolicy; _socketTimeout = socketTimeout; } // SocketCache internal TimeSpan SocketTimeout { get { return _socketTimeout; } set { _socketTimeout = value;} } internal int ReceiveTimeout { get { return _receiveTimeout; } set { _receiveTimeout = value;} } internal SocketCachePolicy CachePolicy { get { return _socketCachePolicy; } set { _socketCachePolicy = value;}} private static void InitializeSocketTimeoutHandler() { _socketTimeoutDelegate = new WaitOrTimerCallback(TimeoutSockets); _socketTimeoutWaitHandle = new AutoResetEvent(false); _registeredWaitHandle = ThreadPool.UnsafeRegisterWaitForSingleObject( _socketTimeoutWaitHandle, _socketTimeoutDelegate, "TcpChannelSocketTimeout", _socketTimeoutPollTime, true); // execute only once } // InitializeSocketTimeoutHandler private static void TimeoutSockets(Object state, Boolean wasSignalled) { DateTime currentTime = DateTime.UtcNow; lock (_connections) { foreach (DictionaryEntry entry in _connections) { RemoteConnection connection = (RemoteConnection)entry.Value; connection.TimeoutSockets(currentTime); } } _registeredWaitHandle.Unregister(null); _registeredWaitHandle = ThreadPool.UnsafeRegisterWaitForSingleObject( _socketTimeoutWaitHandle, _socketTimeoutDelegate, "TcpChannelSocketTimeout", _socketTimeoutPollTime, true); // execute only once } // TimeoutSockets internal SocketHandler CreateSocketHandler(Socket socket, String machineAndPort) { socket.ReceiveTimeout = _receiveTimeout; return _handlerFactory(socket, this, machineAndPort); } // The key is expected to of the form "machinename:port" public SocketHandler GetSocket(String machinePortAndSid, bool openNew) { RemoteConnection connection = (RemoteConnection)_connections[machinePortAndSid]; if (openNew || connection == null) { connection = new RemoteConnection(this, machinePortAndSid); // doesn't matter if different RemoteConnection's get written at // the same time (GC will come along and close them). lock (_connections) { _connections[machinePortAndSid] = connection; } } return connection.GetSocket(); } // GetSocket public void ReleaseSocket(String machinePortAndSid, SocketHandler socket) { RemoteConnection connection = (RemoteConnection)_connections[machinePortAndSid]; if (connection != null) { connection.ReleaseSocket(socket); } else { // there should have been a connection, so let's just close // this socket. socket.Close(); } } // ReleaseSocket } // SocketCache } // namespace System.Runtime.Remoting.Channels // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WinCategoryAttribute.cs
- ListViewInsertedEventArgs.cs
- TrailingSpaceComparer.cs
- OleDbErrorCollection.cs
- IProvider.cs
- Rect3D.cs
- NeutralResourcesLanguageAttribute.cs
- FrameworkPropertyMetadata.cs
- ToolboxDataAttribute.cs
- Point3DConverter.cs
- CompositionTarget.cs
- SiteIdentityPermission.cs
- FloatAverageAggregationOperator.cs
- EntityWithChangeTrackerStrategy.cs
- EdmSchemaAttribute.cs
- Tablet.cs
- FontStretches.cs
- PanelStyle.cs
- X509ChainPolicy.cs
- PenThreadPool.cs
- InputManager.cs
- TextTreeUndoUnit.cs
- InlinedAggregationOperator.cs
- AudioException.cs
- PageParser.cs
- QueryableFilterUserControl.cs
- XmlQueryType.cs
- DetailsViewDeleteEventArgs.cs
- PropertyFilterAttribute.cs
- FileSecurity.cs
- ICspAsymmetricAlgorithm.cs
- MeasurementDCInfo.cs
- RepeaterItemCollection.cs
- DbUpdateCommandTree.cs
- ConfigurationPropertyCollection.cs
- DrawingServices.cs
- PlanCompilerUtil.cs
- HostExecutionContextManager.cs
- TextServicesManager.cs
- FastEncoderWindow.cs
- DataTableMappingCollection.cs
- TextParaLineResult.cs
- EntityProviderFactory.cs
- CompilerGeneratedAttribute.cs
- DocobjHost.cs
- InlineCollection.cs
- XamlDebuggerXmlReader.cs
- DocumentGrid.cs
- OdbcEnvironment.cs
- XmlDataSourceView.cs
- NegotiateStream.cs
- AutoFocusStyle.xaml.cs
- CallbackException.cs
- CustomTrackingQuery.cs
- SmtpFailedRecipientException.cs
- Missing.cs
- SHA1CryptoServiceProvider.cs
- WebBrowserNavigatingEventHandler.cs
- FileDataSourceCache.cs
- TextTreeUndo.cs
- MembershipSection.cs
- ProviderCommandInfoUtils.cs
- TemplatedAdorner.cs
- XmlResolver.cs
- ListViewGroupConverter.cs
- RoutedEventValueSerializer.cs
- AssemblyCache.cs
- CreateWorkflowOwnerCommand.cs
- TypeForwardedToAttribute.cs
- WebControlParameterProxy.cs
- IntSecurity.cs
- datacache.cs
- ToolboxBitmapAttribute.cs
- PermissionListSet.cs
- cookiecontainer.cs
- BinHexEncoding.cs
- CommonProperties.cs
- DynamicDataResources.Designer.cs
- AttributeProviderAttribute.cs
- DataObjectPastingEventArgs.cs
- ExtendedProtectionPolicyTypeConverter.cs
- DocumentPageView.cs
- GeometryCombineModeValidation.cs
- CodeFieldReferenceExpression.cs
- ProjectionRewriter.cs
- PtsPage.cs
- PlainXmlSerializer.cs
- DesignConnection.cs
- DBParameter.cs
- GraphicsContext.cs
- SmtpLoginAuthenticationModule.cs
- RequestQueue.cs
- ResourceLoader.cs
- ReferentialConstraint.cs
- StorageConditionPropertyMapping.cs
- CodeChecksumPragma.cs
- SecurityTokenProvider.cs
- ToolStripItem.cs
- PieceDirectory.cs
- WrapPanel.cs