bug 738812 timer serviced after thread exit nsHttpConnectionMgr::ReadTimeoutTick r=honzab
authorPatrick McManus <mcmanus@ducksong.com>
Wed, 11 Apr 2012 13:11:09 -0400
changeset 91452 69e021051aa5cba60022da60a3a96aa5ffcb7ba2
parent 91451 6854bda609ae11affa58bc561b4d515e5ce4d712
child 91453 d770f8c6e19b7ab64fb60adbe458429c9f434d1d
push id22445
push usereakhgari@mozilla.com
push dateThu, 12 Apr 2012 16:19:55 +0000
treeherdermozilla-central@901dfde60183 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershonzab
bugs738812
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 738812 timer serviced after thread exit nsHttpConnectionMgr::ReadTimeoutTick r=honzab
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpConnectionMgr.h
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -249,16 +249,34 @@ nsHttpConnectionMgr::ConditionallyStopPr
     // Reset mTimeOfNextWakeUp so that we can find a new shortest value.
     mTimeOfNextWakeUp = LL_MAXUINT;
     if (mTimer) {
         mTimer->Cancel();
         mTimer = NULL;
     }
 }
 
+void
+nsHttpConnectionMgr::ConditionallyStopReadTimeoutTick()
+{
+    LOG(("nsHttpConnectionMgr::ConditionallyStopReadTimeoutTick "
+         "armed=%d active=%d\n", mReadTimeoutTickArmed, mNumActiveConns));
+
+    if (!mReadTimeoutTickArmed)
+        return;
+
+    if (mNumActiveConns)
+        return;
+
+    LOG(("nsHttpConnectionMgr::ConditionallyStopReadTimeoutTick stop==true\n"));
+
+    mReadTimeoutTick->Cancel();
+    mReadTimeoutTickArmed = false;
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpConnectionMgr::nsIObserver
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsHttpConnectionMgr::Observe(nsISupports *subject,
                              const char *topic,
                              const PRUnichar *data)
@@ -1453,16 +1471,18 @@ nsHttpConnectionMgr::DispatchTransaction
 
     rv = conn->Activate(pipeline, caps, priority);
     if (NS_FAILED(rv)) {
         LOG(("  conn->Activate failed [rv=%x]\n", rv));
         ent->mActiveConns.RemoveElement(conn);
         if (conn == ent->mYellowConnection)
             ent->OnYellowComplete();
         mNumActiveConns--;
+        ConditionallyStopReadTimeoutTick();
+
         // sever back references to connection, and do so without triggering
         // a call to ReclaimConnection ;-)
         pipeline->SetConnection(nsnull);
         NS_RELEASE(handle->mConn);
         // destroy the connection
         NS_RELEASE(conn);
     }
 
@@ -1584,16 +1604,17 @@ nsHttpConnectionMgr::StartedConnect()
 {
     mNumActiveConns++;
 }
 
 void
 nsHttpConnectionMgr::RecvdConnect()
 {
     mNumActiveConns--;
+    ConditionallyStopReadTimeoutTick();
 }
 
 nsresult
 nsHttpConnectionMgr::CreateTransport(nsConnectionEntry *ent,
                                      nsHttpTransaction *trans)
 {
     NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
 
@@ -1863,16 +1884,17 @@ nsHttpConnectionMgr::OnMsgReclaimConnect
         }
         
         if (ent->mActiveConns.RemoveElement(conn)) {
             if (conn == ent->mYellowConnection)
                 ent->OnYellowComplete();
             nsHttpConnection *temp = conn;
             NS_RELEASE(temp);
             mNumActiveConns--;
+            ConditionallyStopReadTimeoutTick();
         }
 
         if (conn->CanReuse()) {
             LOG(("  adding connection to idle list\n"));
             // 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.
 
@@ -1996,22 +2018,16 @@ void
 nsHttpConnectionMgr::ReadTimeoutTick()
 {
     NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
     NS_ABORT_IF_FALSE(mReadTimeoutTick, "no readtimeout tick");
 
     LOG(("nsHttpConnectionMgr::ReadTimeoutTick active=%d\n",
          mNumActiveConns));
 
-    if (!mNumActiveConns && mReadTimeoutTickArmed) {
-        mReadTimeoutTick->Cancel();
-        mReadTimeoutTickArmed = false;
-        return;
-    }
-
     mCT.Enumerate(ReadTimeoutTickCB, this);
 }
 
 PLDHashOperator
 nsHttpConnectionMgr::ReadTimeoutTickCB(const nsACString &key,
                                        nsAutoPtr<nsConnectionEntry> &ent,
                                        void *closure)
 {
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -100,16 +100,20 @@ public:
     // Schedules next pruning of dead connection to happen after
     // given time.
     void PruneDeadConnectionsAfter(PRUint32 time);
 
     // Stops timer scheduled for next pruning of dead connections if
     // there are no more idle connections or active spdy ones
     void ConditionallyStopPruneDeadConnectionsTimer();
 
+    // Stops timer used for the read timeout tick if there are no currently
+    // active connections.
+    void ConditionallyStopReadTimeoutTick();
+
     // adds a transaction to the list of managed transactions.
     nsresult AddTransaction(nsHttpTransaction *, PRInt32 priority);
 
     // called to reschedule the given transaction.  it must already have been
     // added to the connection manager via AddTransaction.
     nsresult RescheduleTransaction(nsHttpTransaction *, PRInt32 priority);
 
     // cancels a transaction w/ the given reason.