public ServicePointScheduler(ServicePoint servicePoint, int connectionLimit, int maxIdleTime) { ServicePoint = servicePoint; this.connectionLimit = connectionLimit; this.maxIdleTime = maxIdleTime; schedulerEvent = new AsyncManualResetEvent(false); defaultGroup = new ConnectionGroup(this, string.Empty); operations = new LinkedList <(ConnectionGroup, WebOperation)> (); idleConnections = new LinkedList <(ConnectionGroup, WebConnection, Task)> (); idleSince = DateTime.UtcNow; }
private ConnectionGroup FindConnectionGroup(string connName, bool dontCreate) { string str = ConnectionGroup.MakeQueryStr(connName); ConnectionGroup group = this.m_ConnectionGroupList[str] as ConnectionGroup; if ((group == null) && !dontCreate) { group = new ConnectionGroup(this, connName); this.m_ConnectionGroupList[str] = group; } return(group); }
internal bool ReleaseConnectionGroup(string connName) { lock (this) { ConnectionGroup group = this.FindConnectionGroup(connName, true); if (group == null) { return(false); } group.DisableKeepAliveOnConnections(); this.m_ConnectionGroupList.Remove(connName); } return(true); }
private void SetConnectionLimit(int limit, bool fromUser) { lock (this) { // We'll only update the limit if the user hasn't previously // changed it or if this change is coming from the user. if (!m_UserChangedLimit || fromUser) { // Save the value, and remember if it was changed by the // user. m_UserChangedLimit = fromUser; m_ConnectionLimit = limit; // Now walk through the connection groups on this service // point, and update all of them with the new value. // IDictionaryEnumerator CGEnumerator; CGEnumerator = m_ConnectionGroupList.GetEnumerator(); while (CGEnumerator.MoveNext()) { ConnectionGroup CurrentCG = (ConnectionGroup)CGEnumerator.Value; // // If this change came in from the user, we want to // propagate it down to the underlying connection // groups no matter what. If it's from some internal state // change, we want to propagate it via the internal // mechanism, which only sets it if it hasn't been set by // the user. if (fromUser) { CurrentCG.ConnectionLimit = limit; } else { CurrentCG.InternalConnectionLimit = limit; } } } } }
/// <devdoc> /// <para> /// Sets connections in this group to not be KeepAlive. /// This is called to force cleanup of the ConnectionGroup by the /// NTLM and Negotiate authentication modules. /// </para> /// </devdoc> internal void ReleaseConnectionGroup(string connName) { // // look up the ConnectionGroup based on the name // ConnectionGroup connectionGroup = FindConnectionGroup(connName); // // force all connections on the ConnectionGroup to not be KeepAlive // connectionGroup.DisableKeepAliveOnConnections(); // // remove ConnectionGroup from our Hashtable // lock (this) { m_ConnectionGroupList.Remove(connName); } }
private ConnectionGroup FindConnectionGroup(string connName, bool dontCreate) { string str = ConnectionGroup.MakeQueryStr(connName); ConnectionGroup group = this.m_ConnectionGroupList[str] as ConnectionGroup; if ((group == null) && !dontCreate) { group = new ConnectionGroup(this, connName); this.m_ConnectionGroupList[str] = group; } return group; }
internal Connection(ConnectionGroup connectionGroup) : base(null) { // // add this Connection to the pool in the connection group, // keep a weak reference to it // m_MaximumUnauthorizedUploadLength = SettingsSectionInternal.Section.MaximumUnauthorizedUploadLength; if(m_MaximumUnauthorizedUploadLength > 0){ m_MaximumUnauthorizedUploadLength*=1024; } m_ResponseData = new CoreResponseData(); m_ConnectionGroup = connectionGroup; m_ReadBuffer = new byte[4096]; // Using a fixed 4k read buffer. m_ReadState = ReadState.Start; m_WaitList = new List<WaitListItem>(); m_WriteList = new ArrayList(); m_AbortDelegate = new HttpAbortDelegate(AbortOrDisassociate); m_ConnectionUnlock = new UnlockConnectionDelegate(UnlockRequest); // for status line parsing m_StatusLineValues = new StatusLineValues(); m_RecycleTimer = ConnectionGroup.ServicePoint.ConnectionLeaseTimerQueue.CreateTimer(); // the following line must be the last line of the constructor ConnectionGroup.Associate(this); m_ReadDone = true; m_WriteDone = true; m_Error = WebExceptionStatus.Success; }
/*++ FindConnectionGroup - Searches for the a Group object that actually holds the connections that we want to peak at. Input: request - Request that's being submitted. connName - Connection Name if needed Returns: ConnectionGroup --*/ private ConnectionGroup FindConnectionGroup(string connName, bool dontCreate) { string lookupStr = ConnectionGroup.MakeQueryStr(connName); GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() lookupStr:[" + ValidationHelper.ToString(connName) + "]"); ConnectionGroup entry = m_ConnectionGroupList[lookupStr] as ConnectionGroup; if (entry==null && !dontCreate) { entry = new ConnectionGroup(this, connName); GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() adding ConnectionGroup lookupStr:[" + lookupStr + "]"); m_ConnectionGroupList[lookupStr] = entry; } else { GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() using existing ConnectionGroup"); } GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() returning ConnectionGroup:" + ValidationHelper.ToString(entry) + (entry!=null ? " ConnLimit:" + entry.ConnectionLimit.ToString() : "")); return entry; }
internal TimerThread.Timer CreateConnectionGroupTimer(ConnectionGroup connectionGroup) { return m_IdlingQueue.CreateTimer(m_IdleConnectionGroupTimeoutDelegate, connectionGroup); }
internal Connection(ConnectionGroup connectionGroup) : base(null) { // // add this Connection to the pool in the connection group, // keep a weak reference to it // m_MaximumUnauthorizedUploadLength = SettingsSectionInternal.Section.MaximumUnauthorizedUploadLength; if(m_MaximumUnauthorizedUploadLength > 0){ m_MaximumUnauthorizedUploadLength*=1024; } m_ResponseData = new CoreResponseData(); m_ConnectionGroup = connectionGroup; m_ReadBuffer = s_PinnableBufferCache.AllocateBuffer(); m_ReadBufferFromPinnableCache = true; m_ReadState = ReadState.Start; m_WaitList = new List<WaitListItem>(); m_WriteList = new ArrayList(); m_AbortDelegate = new HttpAbortDelegate(AbortOrDisassociate); m_ConnectionUnlock = new UnlockConnectionDelegate(UnlockRequest); // for status line parsing m_StatusLineValues = new StatusLineValues(); m_RecycleTimer = ConnectionGroup.ServicePoint.ConnectionLeaseTimerQueue.CreateTimer(); // the following line must be the last line of the constructor ConnectionGroup.Associate(this); m_ReadDone = true; m_WriteDone = true; m_Error = WebExceptionStatus.Success; if (PinnableBufferCacheEventSource.Log.IsEnabled()) { PinnableBufferCacheEventSource.Log.DebugMessage1("CTOR: In System.Net.Connection.Connnection", this.GetHashCode()); } }
// methods /*++ FindConnectionGroup - Searches for the a Group object that actually holds the connections that we want to peak at. Input: request - Request that's being submitted. connName - Connection Name if needed Returns: ConnectionGroup --*/ internal ConnectionGroup FindConnectionGroup(string connName) { string lookupStr = ConnectionGroup.MakeQueryStr(connName); GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() lookupStr:[" + ValidationHelper.ToString(connName) + "]"); ConnectionGroup entry = m_ConnectionGroupList[lookupStr] as ConnectionGroup; if (entry == null) { IPAddressInfo RemoteInfo = GetCurrentIPAddressInfo(); IPAddress RemoteAddress = null; int ConnLimit; if (RemoteInfo == null) { GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() RemoteAddress:[(null)] m_UserChangedLimit:" + m_UserChangedLimit.ToString() + " m_ConnectionLimit:" + m_ConnectionLimit.ToString()); // // If we don't have any information about the remote IP address, // limit ourself to one connection until the address is resolved. // ConnLimit = 1; // ServicePointManager.DefaultConnectionLimit; // // if this is a user given number, then // make sure to propagte this value // if (m_UserChangedLimit) { ConnLimit = m_ConnectionLimit; } } else { RemoteAddress = RemoteInfo.Address; if (!RemoteInfo.IsLoopback) { ConnLimit = m_ConnectionLimit; } else { ConnLimit = LoopbackConnectionLimit; } GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() RemoteAddress:[" + RemoteAddress.ToString() + "] ConnLimit:" + ConnLimit.ToString() + " m_ConnectionLimit:" + m_ConnectionLimit.ToString()); } GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() creating ConnectionGroup ConnLimit:" + ConnLimit.ToString()); entry = new ConnectionGroup(this, RemoteAddress, ConnLimit, connName); GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() adding ConnectionGroup lookupStr:[" + lookupStr + "]"); m_ConnectionGroupList[lookupStr] = entry; } else { GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() using existing ConnectionGroup"); } GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() ConnectionGroup.ConnLimit:" + entry.ConnectionLimit.ToString()); return entry; }
public Connection( ConnectionGroup connectionGroup, ServicePoint servicePoint, IPAddress remoteAddress, Version version, bool supportsPipeline ) { // // add this Connection to the pool in the connection group, // keep a weak reference to it // m_ConnectionGroup = connectionGroup; m_WeakReference = new WeakReference(this); m_ConnectionGroup.Associate(m_WeakReference); m_Idle = true; m_Free = true; m_CanPipeline = supportsPipeline; m_Server = servicePoint; m_Version = version; m_ReadBuffer = new byte[m_ReadBufferSize]; m_CurrentRequestIndex = 0; m_ReadState = ReadState.Start; m_WaitList = new ArrayList(); m_WriteList = new ArrayList(); m_ReadCallbackEvent = new ManualResetEvent(true); m_StartConnectionDelegate = new WaitOrTimerCallback(StartConnectionCallback); m_AbortDelegate = new HttpAbortDelegate(Abort); // for status line parsing m_StatusLineInts = new int[MaxStatusInts]; InitializeParseStatueLine(); }
/*++ * * SetAddressList - Set the list of IP addresses for this service point. * * This is a method called when the underlying code has resolved the * destination to a list of IP addressess. We actually maintain some * information about the viable IP addresses for this service point, * like whether or not they're loopback, etc. So we walk through the * list and set up an array of structures corresponding to the IP * addresses. * * Note that it's possible to have some IP addresses be loopbacked * and some not. This can happen if a server name maps to multiple * physical servers and we're one of those servers. * * Input: * addressList - Array of resolved IP addresses. * * Returns: Nothing. * * --*/ private IPHostEntryInfo SetAddressList(IPHostEntry ipHostEntry) { GlobalLog.Print("SetAddressList(" + ipHostEntry.HostName + ")"); // // Create an array of IPAddressInfo of the appropriate size, then // get a list of our local addresses. Walk through the input // address list. Copy each address in the address list into // our array, and if the address is a loopback address, mark it as // such. // IPAddress[] addressList = ipHostEntry.AddressList; IPAddressInfo[] TempInfo = new IPAddressInfo[addressList.Length]; // // Walk through each member of the input list, copying it into our temp array. // int i, k; IPHostEntry ipLocalHostEntry = null; try { ipLocalHostEntry = Dns.LocalHost; } catch (Exception exception) { GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::SetAddressList() Dns.LocalHost threw exception:[" + ValidationHelper.ToString(exception) + "]"); } for (i = 0; i < addressList.Length; i++) { TempInfo[i] = new IPAddressInfo(addressList[i]); // First, check to see if the current address is a loopback // address. if (IPAddress.IsLoopback(TempInfo[i].Address)) { TempInfo[i].IsLoopback = true; continue; } // See if the current IP address is a local address, and if // so mark it as such. if (ipLocalHostEntry != null) { for (k = 0; k < ipLocalHostEntry.AddressList.Length; k++) { // // IPv6 Changes: Use .Equals for this check ! // if (TempInfo[i].Address.Equals(ipLocalHostEntry.AddressList[k])) { TempInfo[i].IsLoopback = true; break; } } } } // // now look for connection group objects that don't have // an IP address associated with them. When it finds one, it updates // the IP address and tries to update the connection limit. // lock (this) { // Walk through the connection groups on this service // point, and update the ones we need to with an IP // address. // IDictionaryEnumerator CGEnumerator; CGEnumerator = m_ConnectionGroupList.GetEnumerator(); while (CGEnumerator.MoveNext()) { ConnectionGroup CurrentCG = (ConnectionGroup)CGEnumerator.Value; // If this connection group doesn't have an IP address // assigned to it, give it one. if (CurrentCG.RemoteIPAddress == null) { GlobalLog.Print("ServicePoint::UpdateConnectionGroupAddresses null CurrentCG.RemoteIPAddress"); // Update the address. CurrentCG.RemoteIPAddress = TempInfo[0].Address; // Now update the connection limit based on what we know. CurrentCG.InternalConnectionLimit = TempInfo[0].IsLoopback ? LoopbackConnectionLimit : m_ConnectionLimit; GlobalLog.Print("ServicePoint::UpdateConnectionGroupAddresses CurrentCG.InternalConnectionLimit:" + CurrentCG.InternalConnectionLimit.ToString()); } GlobalLog.Print("ServicePoint::UpdateConnectionGroupAddresses CurrentCG.RemoteIPAddress:" + CurrentCG.RemoteIPAddress.ToString()); } } IPHostEntryInfo ipAddressInfoList = new IPHostEntryInfo(TempInfo, ipHostEntry.HostName); return(ipAddressInfoList); }
// methods /*++ * * FindConnectionGroup - * * Searches for the a Group object that actually holds the connections * that we want to peak at. * * * Input: * request - Request that's being submitted. * connName - Connection Name if needed * * Returns: * ConnectionGroup * * --*/ internal ConnectionGroup FindConnectionGroup(string connName) { string lookupStr = ConnectionGroup.MakeQueryStr(connName); GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() lookupStr:[" + ValidationHelper.ToString(connName) + "]"); ConnectionGroup entry = m_ConnectionGroupList[lookupStr] as ConnectionGroup; if (entry == null) { IPAddressInfo RemoteInfo = GetCurrentIPAddressInfo(); IPAddress RemoteAddress = null; int ConnLimit; if (RemoteInfo == null) { GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() RemoteAddress:[(null)] m_UserChangedLimit:" + m_UserChangedLimit.ToString() + " m_ConnectionLimit:" + m_ConnectionLimit.ToString()); // // If we don't have any information about the remote IP address, // limit ourself to one connection until the address is resolved. // ConnLimit = 1; // ServicePointManager.DefaultConnectionLimit; // // if this is a user given number, then // make sure to propagte this value // if (m_UserChangedLimit) { ConnLimit = m_ConnectionLimit; } } else { RemoteAddress = RemoteInfo.Address; if (!RemoteInfo.IsLoopback) { ConnLimit = m_ConnectionLimit; } else { ConnLimit = LoopbackConnectionLimit; } GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() RemoteAddress:[" + RemoteAddress.ToString() + "] ConnLimit:" + ConnLimit.ToString() + " m_ConnectionLimit:" + m_ConnectionLimit.ToString()); } GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() creating ConnectionGroup ConnLimit:" + ConnLimit.ToString()); entry = new ConnectionGroup(this, RemoteAddress, ConnLimit, connName); GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() adding ConnectionGroup lookupStr:[" + lookupStr + "]"); m_ConnectionGroupList[lookupStr] = entry; } else { GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() using existing ConnectionGroup"); } GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() ConnectionGroup.ConnLimit:" + entry.ConnectionLimit.ToString()); return(entry); }