From c742414ab8861b60d009eb739427c6d8bdebc88a Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Fri, 8 Apr 2011 14:36:47 -0400 Subject: [PATCH] 624739 - sort idle persistent http connections by pereceived server cwnd --HG-- extra : rebase_source : 29c50d0c0e99220bb87b5f584188fad49cc33439 --- netwerk/protocol/http/nsHttpConnection.cpp | 25 +++++++++++++------ netwerk/protocol/http/nsHttpConnection.h | 3 +++ netwerk/protocol/http/nsHttpConnectionMgr.cpp | 20 ++++++++++++--- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp index a3e713e6c74f..47e1a07c4918 100644 --- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -70,6 +70,8 @@ nsHttpConnection::nsHttpConnection() , mIdleTimeout(0) , mConsiderReusedAfterInterval(0) , mConsiderReusedAfterEpoch(0) + , mCurrentBytesRead(0) + , mMaxBytesRead(0) , mKeepAlive(PR_TRUE) // assume to keep-alive by default , mKeepAliveMask(PR_TRUE) , mSupportsPipelining(PR_FALSE) // assume low-grade server @@ -161,6 +163,9 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, PRUint8 caps) goto failed_activation; } + // Clear the per activation counter + mCurrentBytesRead = 0; + rv = OnOutputStreamReady(mSocketOut); failed_activation: @@ -502,6 +507,9 @@ nsHttpConnection::CloseTransaction(nsAHttpTransaction *trans, nsresult reason) NS_ASSERTION(trans == mTransaction, "wrong transaction"); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); + if (mCurrentBytesRead > mMaxBytesRead) + mMaxBytesRead = mCurrentBytesRead; + // mask this error code because its not a real error. if (reason == NS_BASE_STREAM_CLOSED) reason = NS_OK; @@ -677,13 +685,16 @@ nsHttpConnection::OnSocketReadable() rv = NS_OK; again = PR_FALSE; } - else if (NS_FAILED(mSocketInCondition)) { - // continue waiting for the socket if necessary... - if (mSocketInCondition == NS_BASE_STREAM_WOULD_BLOCK) - rv = mSocketIn->AsyncWait(this, 0, 0, nsnull); - else - rv = mSocketInCondition; - again = PR_FALSE; + else { + mCurrentBytesRead += n; + if (NS_FAILED(mSocketInCondition)) { + // continue waiting for the socket if necessary... + if (mSocketInCondition == NS_BASE_STREAM_WOULD_BLOCK) + rv = mSocketIn->AsyncWait(this, 0, 0, nsnull); + else + rv = mSocketInCondition; + again = PR_FALSE; + } } // read more from the socket until error... } while (again); diff --git a/netwerk/protocol/http/nsHttpConnection.h b/netwerk/protocol/http/nsHttpConnection.h index 1a18033284a1..261c05ce28f2 100644 --- a/netwerk/protocol/http/nsHttpConnection.h +++ b/netwerk/protocol/http/nsHttpConnection.h @@ -138,6 +138,7 @@ public: nsresult PushBack(const char *data, PRUint32 length) { NS_NOTREACHED("PushBack"); return NS_ERROR_UNEXPECTED; } nsresult ResumeSend(); nsresult ResumeRecv(); + PRInt64 MaxBytesRead() {return mMaxBytesRead;} static NS_METHOD ReadFromStream(nsIInputStream *, void *, const char *, PRUint32, PRUint32, PRUint32 *); @@ -180,6 +181,8 @@ private: PRUint16 mIdleTimeout; // value of keep-alive: timeout= PRIntervalTime mConsiderReusedAfterInterval; PRIntervalTime mConsiderReusedAfterEpoch; + PRInt64 mCurrentBytesRead; // data read per activation + PRInt64 mMaxBytesRead; // max read in 1 activation PRPackedBool mKeepAlive; PRPackedBool mKeepAliveMask; diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 1b351726b0e2..d233907596c3 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -1057,12 +1057,24 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(PRInt32, void *param) if (conn->CanReuse()) { LOG((" adding connection to idle list\n")); - // hold onto this connection in the idle list. we push it to - // the end of the list so as to ensure that we'll visit older - // connections first before getting to this one. + // Keep The idle connection list sorted with the connections that + // have moved the largest data pipelines at the front because these + // connections have the largest cwnds on the server. + + // The linear search is ok here because the number of idleconns + // in a single entry is generally limited to a small number (i.e. 6) + + PRInt32 idx; + for (idx = 0; idx < ent->mIdleConns.Length(); idx++) { + nsHttpConnection *idleConn = ent->mIdleConns[idx]; + if (idleConn->MaxBytesRead() < conn->MaxBytesRead()) + break; + } + NS_ADDREF(conn); - ent->mIdleConns.AppendElement(conn); + ent->mIdleConns.InsertElementAt(idx, conn); mNumIdleConns++; + // If the added connection was first idle connection or has shortest // time to live among the idle connections, pruning dead // connections needs to be done when it can't be reused anymore.