private Connection FindConnectionAuthenticationGroup(HttpWebRequest request, string connName) {
Connection leastBusyConnection = null;
GlobalLog.Print("ConnectionGroup::FindConnectionAuthenticationGroup [" + connName + "] for request#" + request.GetHashCode() +", m_ConnectionList.Count:" + m_ConnectionList.Count.ToString());
//
// First try and find a free Connection (i.e. one not busy with Authentication handshake)
// or try to find a Request that has already locked a specific Connection,
// if a matching Connection is found, then we're done
//
lock (m_ConnectionList) {
Connection matchingConnection;
matchingConnection = FindMatchingConnection(request, connName, out leastBusyConnection);
if (matchingConnection != null) {
return matchingConnection;
}
if (AuthenticationRequestQueue.Count == 0) {
if (leastBusyConnection != null) {
if (request.LockConnection) {
m_NtlmNegGroup = true;
m_IISVersion = leastBusyConnection.IISVersion;
}
if(request.LockConnection || (m_NtlmNegGroup && !request.Pipelined && request.UnsafeOrProxyAuthenticatedConnectionSharing && m_IISVersion >= 6)){
GlobalLog.Print("Assigning New Locked Request#" + request.GetHashCode().ToString());
leastBusyConnection.LockedRequest = request;
}
return leastBusyConnection;
}
}
else if (leastBusyConnection != null) {
AsyncWaitHandle.Set();
}
AuthenticationRequestQueue.Enqueue(request);
}
//
// If all the Connections are busy, then we queue ourselves and need to wait. As soon as
// one of the Connections are free, we grab the lock, and see if we find ourselves
// at the head of the queue. If not, we loop backaround.
// Care is taken to examine the request when we wakeup, in case the request is aborted.
//
while (true) {
GlobalLog.Print("waiting");
request.AbortDelegate = m_AbortDelegate;
if (!request.Aborted)
AsyncWaitHandle.WaitOne();
GlobalLog.Print("wait up");
lock(m_ConnectionList) {
if (request.Aborted)
{
PruneAbortedRequests();
// Note that request is not on any connection and it will not be submitted
return null;
}
FindMatchingConnection(request, connName, out leastBusyConnection);
if (AuthenticationRequestQueue.Peek() == request) {
GlobalLog.Print("dequeue");
AuthenticationRequestQueue.Dequeue();
if (leastBusyConnection != null) {
if (request.LockConnection) {
m_NtlmNegGroup = true;
m_IISVersion = leastBusyConnection.IISVersion;
}
if(request.LockConnection || (m_NtlmNegGroup && !request.Pipelined && request.UnsafeOrProxyAuthenticatedConnectionSharing && m_IISVersion >= 6)){
leastBusyConnection.LockedRequest = request;
}
return leastBusyConnection;
}
AuthenticationRequestQueue.Enqueue(request);
}
if (leastBusyConnection == null) {
AsyncWaitHandle.Reset();
}
}
}
}