Exemple #1
0
        /// <devdoc>
        ///    <para>
        ///       Attempts to match a request with a connection, if a connection is unassigned ie not locked with
        ///         a request, then the least busy connections is returned in "leastbusyConnection."  If the
        ///         connection limit allows, and all connections are busy, a new one is allocated and returned.
        ///
        ///     RETURNS: a Connection shown to match a previously locked Request/Connection (OTHERWISE)
        ///              leasebusyConnection - will contain a newly allocated Connection or least Busy one
        ///              suiteable for requests.
        ///
        ///     NOTE: For Whidbey: try to integrate this code into FindConnection()
        ///    </para>
        /// </devdoc>
        private Connection FindMatchingConnection(HttpWebRequest request, string connName, out Connection leastbusyConnection)
        {
            int  minBusyCount         = Int32.MaxValue;
            bool freeConnectionsAvail = false;

            leastbusyConnection = null;

            lock (m_ConnectionList) {
                //
                // go through the list of open connections to this service point and pick the first free one or,
                // if none is free, pick the least busy one. Skip all connections with non keep-alive request pipelined.
                //
                minBusyCount = Int32.MaxValue;
                foreach (Connection currentConnection in m_ConnectionList)
                {
                    GlobalLog.Print("ConnectionGroup::FindMatchingConnection currentConnection.BusyCount:" + currentConnection.BusyCount.ToString());

                    if (currentConnection.LockedRequest == request)
                    {
                        leastbusyConnection = currentConnection;
                        return(currentConnection);
                    }

                    GlobalLog.Print("ConnectionGroup::FindMatchingConnection: lockedRequest# " + ((currentConnection.LockedRequest == null) ? "null" : currentConnection.LockedRequest.GetHashCode().ToString()));
                    if (!currentConnection.NonKeepAliveRequestPipelined && currentConnection.BusyCount < minBusyCount && currentConnection.LockedRequest == null)
                    {
                        leastbusyConnection = currentConnection;
                        minBusyCount        = currentConnection.BusyCount;
                        if (minBusyCount == 0)
                        {
                            freeConnectionsAvail = true;
                        }
                    }
                }

                //
                // If there is NOT a Connection free, then we allocate a new Connection
                //
                if (!freeConnectionsAvail && CurrentConnections < ConnectionLimit)
                {
                    //
                    // If we can create a new connection, then do it,
                    // this may have complications in pipeling because
                    // we may wish to optimize this case by actually
                    // using existing connections, rather than creating new ones
                    //
                    // Note: this implicately results in a this.Associate being called.
                    //

                    GlobalLog.Print("ConnectionGroup::FindMatchingConnection [returning new Connection] CurrentConnections:" + CurrentConnections.ToString() + " ConnectionLimit:" + ConnectionLimit.ToString());
                    leastbusyConnection = new Connection(this);
                }
            }

            return(null); // only if we have a locked Connection that matches can return non-null
        }
Exemple #2
0
        /// <devdoc>
        ///    <para>
        ///       Used by the ServicePoint to find a free or new Connection
        ///       for use in making Requests.  Under NTLM and Negotiate requests,
        ///       this function depricates itself and switches the object over to
        ///       using a new code path (see FindConnectionAuthenticationGroup).
        ///    </para>
        /// </devdoc>
        internal Connection FindConnection(HttpWebRequest request, string connName, out bool forcedsubmit)
        {
            Connection leastbusyConnection  = null;
            Connection newConnection        = null;
            bool       freeConnectionsAvail = false;

            forcedsubmit = false;

            if (m_AuthenticationGroup || request.LockConnection)
            {
                m_AuthenticationGroup = true;
                return(FindConnectionAuthenticationGroup(request, connName));
            }

            GlobalLog.Print("ConnectionGroup::FindConnection [" + connName + "] m_ConnectionList.Count:" + m_ConnectionList.Count.ToString());

            lock (m_ConnectionList) {
                //
                // go through the list of open connections to this service point and pick the connection as follows:
                //  - free connection
                //  - if there is no free connection and if we are under connection limit, create new connection
                //  - pick the least busy connection which does not have non-keep alive request pipelined
                //  - pick the least busy connection which may have non-keep alive request pipelined
                // If we pick the connection with non keep-alive request pipelined on it, we set forcedsubmit to true.
                // This will make sure that we don't start the request immediately and it gets queued on the connection.
                //
                int  minBusyCount        = Int32.MaxValue;
                bool foundLiveConnection = false;
                foreach (Connection currentConnection in m_ConnectionList)
                {
                    GlobalLog.Print("ConnectionGroup::FindConnection currentConnection.BusyCount:" + currentConnection.BusyCount.ToString());

                    bool useThisConnection = false;

                    if (foundLiveConnection)
                    {
                        useThisConnection = (!currentConnection.NonKeepAliveRequestPipelined && minBusyCount > currentConnection.BusyCount);
                    }
                    else
                    {
                        useThisConnection = (!currentConnection.NonKeepAliveRequestPipelined || minBusyCount > currentConnection.BusyCount);
                    }

                    if (useThisConnection)
                    {
                        leastbusyConnection = currentConnection;
                        minBusyCount        = currentConnection.BusyCount;

                        if (!foundLiveConnection)
                        {
                            foundLiveConnection = !currentConnection.NonKeepAliveRequestPipelined;
                        }
                        else
                        {
                            GlobalLog.Assert(!currentConnection.NonKeepAliveRequestPipelined, "Connection.NonKeepAliveRequestPipelined == false|Non keep-alive request has been pipelined on this connection.");
                        }

                        if (foundLiveConnection && minBusyCount == 0)
                        {
                            freeConnectionsAvail = true;
                            break;
                        }
                    }
                }

                //
                // If there is NOT a Connection free, then we allocate a new Connection
                //
                if (!freeConnectionsAvail && CurrentConnections < ConnectionLimit)
                {
                    //
                    // If we can create a new connection, then do it,
                    // this may have complications in pipeling because
                    // we may wish to optimize this case by actually
                    // using existing connections, rather than creating new ones
                    //
                    // Note: this implicately results in a this.Associate being called.
                    //

                    GlobalLog.Print("ConnectionGroup::FindConnection [returning new Connection] freeConnectionsAvail:" + freeConnectionsAvail.ToString() + " CurrentConnections:" + CurrentConnections.ToString() + " ConnectionLimit:" + ConnectionLimit.ToString());
                    newConnection = new Connection(this);
                    forcedsubmit  = false;
                }
                else
                {
                    //
                    // All connections are busy, use the least busy one
                    //

                    GlobalLog.Print("ConnectionGroup::FindConnection [returning leastbusyConnection] freeConnectionsAvail:" + freeConnectionsAvail.ToString() + " CurrentConnections:" + CurrentConnections.ToString() + " ConnectionLimit:" + ConnectionLimit.ToString());
                    GlobalLog.Assert(leastbusyConnection != null, "Connect.leastbusyConnection != null|All connections have BusyCount equal to Int32.MaxValue.");

                    newConnection = leastbusyConnection;
                    forcedsubmit  = !foundLiveConnection;
                }

                newConnection.MarkAsReserved();
            }

            return(newConnection);
        }
Exemple #3
0
        /// <devdoc>
        ///    <para>
        ///       Used by the ServicePoint to find a free or new Connection
        ///       for use in making Requests.  Under NTLM and Negotiate requests,
        ///       this function depricates itself and switches the object over to
        ///       using a new code path (see FindConnectionAuthenticationGroup).
        ///    </para>
        /// </devdoc>
        internal Connection FindConnection(HttpWebRequest request, string connName)
        {
            Connection leastbusyConnection  = null;
            Connection newConnection        = null;
            bool       freeConnectionsAvail = false;

            if (m_AuthenticationGroup || request.LockConnection)
            {
                m_AuthenticationGroup = true;
                return(FindConnectionAuthenticationGroup(request, connName));
            }

            GlobalLog.Print("ConnectionGroup::FindConnection [" + connName + "] m_ConnectionList.Count:" + m_ConnectionList.Count.ToString());

            lock (m_ConnectionList) {
                //
                // go through the list of open connections to this service point and pick
                // the first empty one or, if none is empty, pick the least busy one.
                //
                int minBusyCount = Int32.MaxValue;
                foreach (Connection currentConnection in m_ConnectionList)
                {
                    GlobalLog.Print("ConnectionGroup::FindConnection currentConnection.BusyCount:" + currentConnection.BusyCount.ToString());
                    if (currentConnection.BusyCount < minBusyCount)
                    {
                        leastbusyConnection = currentConnection;
                        minBusyCount        = currentConnection.BusyCount;
                        if (minBusyCount == 0)
                        {
                            freeConnectionsAvail = true;
                            break;
                        }
                    }
                }


                //
                // If there is NOT a Connection free, then we allocate a new Connection
                //
                if (!freeConnectionsAvail && CurrentConnections < ConnectionLimit)
                {
                    //
                    // If we can create a new connection, then do it,
                    // this may have complications in pipeling because
                    // we may wish to optimize this case by actually
                    // using existing connections, rather than creating new ones
                    //
                    // Note: this implicately results in a this.Associate being called.
                    //

                    GlobalLog.Print("ConnectionGroup::FindConnection [returning new Connection] freeConnectionsAvail:" + freeConnectionsAvail.ToString() + " CurrentConnections:" + CurrentConnections.ToString() + " ConnectionLimit:" + ConnectionLimit.ToString());
                    newConnection = new Connection(this);
                }
                else
                {
                    //
                    // All connections are busy, use the least busy one
                    //

                    GlobalLog.Print("ConnectionGroup::FindConnection [returning leastbusyConnection] freeConnectionsAvail:" + freeConnectionsAvail.ToString() + " CurrentConnections:" + CurrentConnections.ToString() + " ConnectionLimit:" + ConnectionLimit.ToString());
                    GlobalLog.Assert(leastbusyConnection != null, "Connect.leastbusyConnection != null|All connections have BusyCount equal to Int32.MaxValue.");

                    newConnection = leastbusyConnection;
                }
            }

            return(newConnection);
        }