Bug 1011354 - Use a mutex to guard access to nsHttpTransaction::mConnection. r=mcmanus, r=honzab

This commit is contained in:
Valentin Gosu 2014-09-18 22:21:59 +03:00
parent 80c69719d3
commit 9363a1533b
3 changed files with 28 additions and 9 deletions

View File

@ -5077,7 +5077,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
//
nsRefPtr<nsAHttpConnection> conn;
if (authRetry && (mCaps & NS_HTTP_STICKY_CONNECTION)) {
conn = mTransaction->Connection();
conn = mTransaction->GetConnectionReference();
// This is so far a workaround to fix leak when reusing unpersistent
// connection for authentication retry. See bug 459620 comment 4
// for details.
@ -5087,7 +5087,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
nsRefPtr<nsAHttpConnection> stickyConn;
if (mCaps & NS_HTTP_STICKY_CONNECTION)
stickyConn = mTransaction->Connection();
stickyConn = mTransaction->GetConnectionReference();
// at this point, we're done with the transaction
mTransactionTimings = mTransaction->Timings();

View File

@ -88,7 +88,7 @@ LogHeaders(const char *lineStart)
//-----------------------------------------------------------------------------
nsHttpTransaction::nsHttpTransaction()
: mCallbacksLock("transaction mCallbacks lock")
: mLock("transaction lock")
, mRequestSize(0)
, mConnection(nullptr)
, mConnInfo(nullptr)
@ -379,12 +379,21 @@ nsHttpTransaction::Init(uint32_t caps,
return NS_OK;
}
// This method should only be used on the socket thread
nsAHttpConnection *
nsHttpTransaction::Connection()
{
return mConnection;
}
already_AddRefed<nsAHttpConnection>
nsHttpTransaction::GetConnectionReference()
{
MutexAutoLock lock(mLock);
nsRefPtr<nsAHttpConnection> connection = mConnection;
return connection.forget();
}
nsHttpResponseHead *
nsHttpTransaction::TakeResponseHead()
{
@ -448,8 +457,11 @@ nsHttpTransaction::TakeSubTransactions(
void
nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
{
NS_IF_RELEASE(mConnection);
NS_IF_ADDREF(mConnection = conn);
{
MutexAutoLock lock(mLock);
NS_IF_RELEASE(mConnection);
NS_IF_ADDREF(mConnection = conn);
}
if (conn) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsAHttpTransaction*>(this),
@ -460,7 +472,7 @@ nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
void
nsHttpTransaction::GetSecurityCallbacks(nsIInterfaceRequestor **cb)
{
MutexAutoLock lock(mCallbacksLock);
MutexAutoLock lock(mLock);
NS_IF_ADDREF(*cb = mCallbacks);
}
@ -468,7 +480,7 @@ void
nsHttpTransaction::SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks)
{
{
MutexAutoLock lock(mCallbacksLock);
MutexAutoLock lock(mLock);
mCallbacks = aCallbacks;
}
@ -922,8 +934,10 @@ nsHttpTransaction::Close(nsresult reason)
mTimings.responseEnd.IsNull() && !mTimings.responseStart.IsNull())
mTimings.responseEnd = TimeStamp::Now();
if (relConn && mConnection)
if (relConn && mConnection) {
MutexAutoLock lock(mLock);
NS_RELEASE(mConnection);
}
// save network statistics in the end of transaction
SaveNetworkStats(true);
@ -1086,6 +1100,7 @@ nsHttpTransaction::Restart()
mSecurityInfo = 0;
if (mConnection) {
mConnection->DontReuse();
MutexAutoLock lock(mLock);
NS_RELEASE(mConnection);
}

View File

@ -96,6 +96,10 @@ public:
// will drop any reference to the response headers after this call.
nsHttpResponseHead *TakeResponseHead();
// Provides a thread safe reference of the connection
// nsHttpTransaction::Connection should only be used on the socket thread
already_AddRefed<nsAHttpConnection> GetConnectionReference();
// Called to find out if the transaction generated a complete response.
bool ResponseIsComplete() { return mResponseIsComplete; }
@ -181,7 +185,7 @@ private:
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
};
Mutex mCallbacksLock;
Mutex mLock;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsITransportEventSink> mTransportSink;