bug 775515 nshttpconnectionmgr::restrictconnections() for half opens only if they never connected r=honzab

--HG--
extra : rebase_source : d1c27fa7c066f8f25efa7bf4ad78e6df62b7ce22
This commit is contained in:
Patrick McManus 2012-07-20 08:50:18 -04:00
parent a606746336
commit 9c2207a644
2 changed files with 25 additions and 28 deletions

View File

@ -1103,24 +1103,13 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap
return true;
}
PRInt32 totalCount = ent->mActiveConns.Length();
// Add in the in-progress tcp connections, we will assume they are
// keepalive enabled.
PRUint32 pendingHalfOpens = 0;
for (PRUint32 i = 0; i < ent->mHalfOpens.Length(); ++i) {
nsHalfOpenSocket *halfOpen = ent->mHalfOpens[i];
// Exclude half-open's that has already created a usable connection.
// This prevents the limit being stuck on ipv6 connections that
// eventually time out after typical 21 seconds of no ACK+SYN reply.
if (halfOpen->HasConnected())
continue;
++pendingHalfOpens;
}
totalCount += pendingHalfOpens;
// Exclude half-open's that has already created a usable connection.
// This prevents the limit being stuck on ipv6 connections that
// eventually time out after typical 21 seconds of no ACK+SYN reply.
PRUint32 totalCount =
ent->mActiveConns.Length() + ent->UnconnectedHalfOpens();
PRUint16 maxPersistConns;
@ -1185,7 +1174,7 @@ nsHttpConnectionMgr::RestrictConnections(nsConnectionEntry *ent)
// If the restriction is based on a tcp handshake in progress
// let that connect and then see if it was SPDY or not
if (ent->mHalfOpens.Length())
if (ent->UnconnectedHalfOpens())
return true;
// There is a concern that a host is using a mix of HTTP/1 and SPDY.
@ -2313,22 +2302,15 @@ nsHttpConnectionMgr::nsHalfOpenSocket::~nsHalfOpenSocket()
LOG(("Destroying nsHalfOpenSocket [this=%p]\n", this));
if (mEnt) {
// If the removal of the HalfOpenSocket from the mHalfOpens list
// removes the RestrictConnections() throttle then we need to
// process the pending queue.
bool restrictedBeforeRelease =
gHttpHandler->ConnMgr()->RestrictConnections(mEnt);
// A failure to create the transport object at all
// will result in this not being present in the halfopen table
// so ignore failures of RemoveElement()
mEnt->mHalfOpens.RemoveElement(this);
if (restrictedBeforeRelease &&
!gHttpHandler->ConnMgr()->RestrictConnections(mEnt)) {
LOG(("nsHalfOpenSocket %p lifted RestrictConnections() limit.\n"));
// If there are no unconnected half opens left in the array, then
// it is liekly that this dtor transitioned
if (!mEnt->UnconnectedHalfOpens())
gHttpHandler->ConnMgr()->ProcessPendingQForEntry(mEnt);
}
}
}
@ -3030,3 +3012,14 @@ nsConnectionEntry::MaxPipelineDepth(nsAHttpTransaction::Classifier aClass)
return mGreenDepth;
}
PRUint32
nsHttpConnectionMgr::nsConnectionEntry::UnconnectedHalfOpens()
{
PRUint32 unconnectedHalfOpens = 0;
for (PRUint32 i = 0; i < mHalfOpens.Length(); ++i) {
if (!mHalfOpens[i]->HasConnected())
++unconnectedHalfOpens;
}
return unconnectedHalfOpens;
}

View File

@ -261,6 +261,10 @@ private:
nsTArray<nsHttpConnection*> mIdleConns; // idle persistent connections
nsTArray<nsHalfOpenSocket*> mHalfOpens;
// calculate the number of half open sockets that have not had at least 1
// connection complete
PRUint32 UnconnectedHalfOpens();
// Pipeline depths for various states
const static PRUint32 kPipelineUnlimited = 1024; // fully open - extended green
const static PRUint32 kPipelineOpen = 6; // 6 on each conn - normal green