bug 780522 - backout 762162 due to crash a=lsblakk
authorPatrick McManus <mcmanus@ducksong.com>
Thu, 09 Aug 2012 17:31:44 -0400
changeset 100469 ac27ec3a105c87681838b2bf93c2703e04efcfc7
parent 100468 757d9c0a8d0a87950801ba218377fb823a3a4fe7
child 100470 9004df40d089875d533645a17edc25fabea2b72a
push id1253
push usermcmanus@ducksong.com
push dateThu, 09 Aug 2012 21:33:45 +0000
treeherdermozilla-beta@ac27ec3a105c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsblakk
bugs780522, 762162
milestone15.0
bug 780522 - backout 762162 due to crash a=lsblakk
modules/libpref/src/init/all.js
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpConnectionMgr.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -838,20 +838,16 @@ pref("network.http.assoc-req.enforce", f
 // Section 4.8 "High-Throughput Data Service Class"
 pref("network.http.qos", 0);
 
 // The number of milliseconds after sending a SYN for an HTTP connection,
 // to wait before trying a different connection. 0 means do not use a second
 // connection.
 pref("network.http.connection-retry-timeout", 250);
 
-// The number of seconds after sending initial SYN for an HTTP connection
-// to give up if the OS does not give up first
-pref("network.http.connection-timeout", 90);
-
 // Disable IPv6 for backup connections to workaround problems about broken
 // IPv6 connectivity.
 pref("network.http.fast-fallback-to-IPv4", true);
 
 // Try and use SPDY when using SSL
 pref("network.http.spdy.enabled", true);
 pref("network.http.spdy.enabled.v2", true);
 pref("network.http.spdy.enabled.v3", false);
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -1733,17 +1733,16 @@ nsHttpConnectionMgr::AddActiveConn(nsHtt
     mNumActiveConns++;
     ActivateTimeoutTick();
 }
 
 void
 nsHttpConnectionMgr::StartedConnect()
 {
     mNumActiveConns++;
-    ActivateTimeoutTick(); // likely disabled by RecvdConnect()
 }
 
 void
 nsHttpConnectionMgr::RecvdConnect()
 {
     mNumActiveConns--;
     ConditionallyStopReadTimeoutTick();
 }
@@ -2197,52 +2196,20 @@ nsHttpConnectionMgr::ReadTimeoutTickCB(c
                                        nsAutoPtr<nsConnectionEntry> &ent,
                                        void *closure)
 {
     nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
 
     LOG(("nsHttpConnectionMgr::ReadTimeoutTickCB() this=%p host=%s\n",
          self, ent->mConnInfo->Host()));
 
-    // first call the tick handler for each active connection
     PRIntervalTime now = PR_IntervalNow();
     for (PRUint32 index = 0; index < ent->mActiveConns.Length(); ++index)
         ent->mActiveConns[index]->ReadTimeoutTick(now);
 
-    // now check for any stalled half open sockets
-    if (ent->mHalfOpens.Length()) {
-        TimeStamp now = TimeStamp::Now();
-        double maxConnectTime = gHttpHandler->ConnectTimeout();  /* in milliseconds */
-
-        for (PRUint32 index = ent->mHalfOpens.Length(); index > 0; ) {
-            index--;
-
-            nsHalfOpenSocket *half = ent->mHalfOpens[index];
-            double delta = half->Duration(now);
-            // If the socket has timed out, close it so the waiting transaction
-            // will get the proper signal
-            if (delta > maxConnectTime) {
-                LOG(("Force timeout of half open to %s after %.2fms.\n",
-                     ent->mConnInfo->HashKey().get(), delta));
-                if (half->SocketTransport())
-                    half->SocketTransport()->Close(NS_ERROR_NET_TIMEOUT);
-                if (half->BackupTransport())
-                    half->BackupTransport()->Close(NS_ERROR_NET_TIMEOUT);
-            }
-
-            // If this half open hangs around for 5 seconds after we've closed() it
-            // then just abandon the socket.
-            if (delta > maxConnectTime + 5000) {
-                LOG(("Abandon half open to %s after %.2fms.\n",
-                     ent->mConnInfo->HashKey().get(), delta));
-                half->Abandon();
-            }
-        }
-    }
-
     return PL_DHASH_NEXT;
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpConnectionMgr::nsConnectionHandle
 
 nsHttpConnectionMgr::nsConnectionHandle::~nsConnectionHandle()
 {
@@ -2369,18 +2336,34 @@ nsHalfOpenSocket::nsHalfOpenSocket(nsCon
 
 nsHttpConnectionMgr::nsHalfOpenSocket::~nsHalfOpenSocket()
 {
     NS_ABORT_IF_FALSE(!mStreamOut, "streamout not null");
     NS_ABORT_IF_FALSE(!mBackupStreamOut, "backupstreamout not null");
     NS_ABORT_IF_FALSE(!mSynTimer, "syntimer not null");
     LOG(("Destroying nsHalfOpenSocket [this=%p]\n", this));
     
-    if (mEnt)
-        mEnt->RemoveHalfOpen(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"));
+            gHttpHandler->ConnMgr()->ProcessPendingQForEntry(mEnt);
+        }
+    }
 }
 
 nsresult
 nsHttpConnectionMgr::
 nsHalfOpenSocket::SetupStreams(nsISocketTransport **transport,
                                nsIAsyncInputStream **instream,
                                nsIAsyncOutputStream **outstream,
                                bool isBackup)
@@ -2555,31 +2538,19 @@ nsHttpConnectionMgr::nsHalfOpenSocket::A
     if (mBackupStreamOut) {
         gHttpHandler->ConnMgr()->RecvdConnect();
         mBackupStreamOut->AsyncWait(nsnull, 0, 0, nsnull);
         mBackupStreamOut = nsnull;
     }
 
     CancelBackupTimer();
 
-    if (mEnt)
-        mEnt->RemoveHalfOpen(this);
     mEnt = nsnull;
 }
 
-double
-nsHttpConnectionMgr::nsHalfOpenSocket::Duration(mozilla::TimeStamp epoch)
-{
-    if (mPrimarySynStarted.IsNull())
-        return 0;
-
-    return (epoch - mPrimarySynStarted).ToMilliseconds();
-}
-
-
 NS_IMETHODIMP // method for nsITimerCallback
 nsHttpConnectionMgr::nsHalfOpenSocket::Notify(nsITimer *timer)
 {
     NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
     NS_ABORT_IF_FALSE(timer == mSynTimer, "wrong timer");
 
     SetupBackupStreams();
 
@@ -2989,42 +2960,16 @@ nsConnectionEntry::OnPipelineFeedbackInf
         LOG(("transition %s to yellow\n", mConnInfo->Host()));
         mPipelineState = PS_YELLOW;
         mYellowConnection = nsnull;
     }
 }
 
 void
 nsHttpConnectionMgr::
-nsConnectionEntry::RemoveHalfOpen(nsHalfOpenSocket *halfOpen)
-{
-    // A failure to create the transport object at all
-    // will result in it not being present in the halfopen table
-    // so ignore failures of RemoveElement()
-    mHalfOpens.RemoveElement(halfOpen);
-
-    if (!UnconnectedHalfOpens())
-        // perhaps this reverted RestrictConnections()
-        gHttpHandler->ConnMgr()->ProcessPendingQForEntry(this);
-}
-
-
-PRUint32
-nsHttpConnectionMgr::nsConnectionEntry::UnconnectedHalfOpens()
-{
-    PRUint32 unconnectedHalfOpens = 0;
-    for (PRUint32 i = 0; i < mHalfOpens.Length(); ++i) {
-        if (!mHalfOpens[i]->HasConnected())
-            ++unconnectedHalfOpens;
-    }
-    return unconnectedHalfOpens;
-}
-
-void
-nsHttpConnectionMgr::
 nsConnectionEntry::SetYellowConnection(nsHttpConnection *conn)
 {
     NS_ABORT_IF_FALSE(!mYellowConnection && mPipelineState == PS_YELLOW,
                       "yellow connection already set or state is not yellow");
     mYellowConnection = conn;
     mYellowGoodEvents = mYellowBadEvents = 0;
 }
 
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -259,23 +259,16 @@ private:
         ~nsConnectionEntry();
 
         nsHttpConnectionInfo        *mConnInfo;
         nsTArray<nsHttpTransaction*> mPendingQ;    // pending transaction queue
         nsTArray<nsHttpConnection*>  mActiveConns; // active connections
         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();
-
-        // Remove a particular half open socket from the mHalfOpens array
-        void RemoveHalfOpen(nsHalfOpenSocket *);
-
         // 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
         const static PRUint32 kPipelineRestricted = 2;    // 2 on just 1 conn in yellow
         
         nsHttpConnectionMgr::PipeliningState PipelineState();
         void OnPipelineFeedbackInfo(
             nsHttpConnectionMgr::PipelineFeedbackInfoType info,
@@ -389,20 +382,17 @@ private:
                               nsIAsyncInputStream **,
                               nsIAsyncOutputStream **,
                               bool isBackup);
         nsresult SetupPrimaryStreams();
         nsresult SetupBackupStreams();
         void     SetupBackupTimer();
         void     CancelBackupTimer();
         void     Abandon();
-        double   Duration(mozilla::TimeStamp epoch);
-        nsISocketTransport *SocketTransport() { return mSocketTransport; }
-        nsISocketTransport *BackupTransport() { return mBackupTransport; }
-
+        
         nsAHttpTransaction *Transaction() { return mTransaction; }
 
         bool IsSpeculative() { return mSpeculative; }
         void SetSpeculative(bool val) { mSpeculative = val; }
 
         bool HasConnected() { return mHasConnected; }
 
         void PrintDiagnostics(nsCString &log);
@@ -586,18 +576,18 @@ private:
     PRUint16 mNumIdleConns;
 
     // Holds time in seconds for next wake-up to prune dead connections. 
     PRUint64 mTimeOfNextWakeUp;
     // Timer for next pruning of dead connections.
     nsCOMPtr<nsITimer> mTimer;
 
     // A 1s tick to call nsHttpConnection::ReadTimeoutTick on
-    // active http/1 connections and check for orphaned half opens.
-    // Disabled when there are no active or half open connections.
+    // active http/1 connections. Disabled when there are no
+    // active connections.
     nsCOMPtr<nsITimer> mReadTimeoutTick;
     bool mReadTimeoutTickArmed;
 
     //
     // the connection table
     //
     // this table is indexed by connection key.  each entry is a
     // nsConnectionEntry object.
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -171,17 +171,16 @@ nsHttpHandler::nsHttpHandler()
     , mEnableSpdy(false)
     , mSpdyV2(true)
     , mSpdyV3(true)
     , mCoalesceSpdy(true)
     , mUseAlternateProtocol(false)
     , mSpdySendingChunkSize(ASpdySession::kSendingChunkSize)
     , mSpdyPingThreshold(PR_SecondsToInterval(44))
     , mSpdyPingTimeout(PR_SecondsToInterval(8))
-    , mConnectTimeout(90000)
 {
 #if defined(PR_LOGGING)
     gHttpLog = PR_NewLogModule("nsHttp");
 #endif
 
     LOG(("Creating nsHttpHandler [this=%x].\n", this));
 
     NS_ASSERTION(!gHttpHandler, "HTTP handler already created!");
@@ -1193,25 +1192,16 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
     // closing the session.
     if (PREF_CHANGED(HTTP_PREF("spdy.ping-timeout"))) {
         rv = prefs->GetIntPref(HTTP_PREF("spdy.ping-timeout"), &val);
         if (NS_SUCCEEDED(rv))
             mSpdyPingTimeout =
                 PR_SecondsToInterval((PRUint16) clamped(val, 0, 0x7fffffff));
     }
 
-    // The maximum amount of time to wait for socket transport to be
-    // established
-    if (PREF_CHANGED(HTTP_PREF("connection-timeout"))) {
-        rv = prefs->GetIntPref(HTTP_PREF("connection-timeout"), &val);
-        if (NS_SUCCEEDED(rv))
-            // the pref is in seconds, but the variable is in milliseconds
-            mConnectTimeout = clamped(val, 1, 0xffff) * PR_MSEC_PER_SEC;
-    }
-
     // on transition of network.http.diagnostics to true print
     // a bunch of information to the console
     if (pref && PREF_CHANGED(HTTP_PREF("diagnostics"))) {
         rv = prefs->GetBoolPref(HTTP_PREF("diagnostics"), &cVar);
         if (NS_SUCCEEDED(rv) && cVar) {
             if (mConnMgr)
                 mConnMgr->PrintDiagnostics();
         }
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -89,17 +89,16 @@ public:
     bool           IsSpdyEnabled() { return mEnableSpdy; }
     bool           IsSpdyV2Enabled() { return mSpdyV2; }
     bool           IsSpdyV3Enabled() { return mSpdyV3; }
     bool           CoalesceSpdy() { return mCoalesceSpdy; }
     bool           UseAlternateProtocol() { return mUseAlternateProtocol; }
     PRUint32       SpdySendingChunkSize() { return mSpdySendingChunkSize; }
     PRIntervalTime SpdyPingThreshold() { return mSpdyPingThreshold; }
     PRIntervalTime SpdyPingTimeout() { return mSpdyPingTimeout; }
-    PRUint32       ConnectTimeout()  { return mConnectTimeout; }
 
     bool           PromptTempRedirect()      { return mPromptTempRedirect; }
 
     nsHttpAuthCache     *AuthCache() { return &mAuthCache; }
     nsHttpConnectionMgr *ConnMgr()   { return mConnMgr; }
 
     // cache support
     nsresult GetCacheSession(nsCacheStoragePolicy, bool isPrivate, nsICacheSession **);
@@ -362,20 +361,16 @@ private:
     bool           mEnableSpdy;
     bool           mSpdyV2;
     bool           mSpdyV3;
     bool           mCoalesceSpdy;
     bool           mUseAlternateProtocol;
     PRUint32       mSpdySendingChunkSize;
     PRIntervalTime mSpdyPingThreshold;
     PRIntervalTime mSpdyPingTimeout;
-
-    // The maximum amount of time to wait for socket transport to be
-    // established. In milliseconds.
-    PRUint32       mConnectTimeout;
 };
 
 //-----------------------------------------------------------------------------
 
 extern nsHttpHandler *gHttpHandler;
 
 //-----------------------------------------------------------------------------
 // nsHttpsHandler - thin wrapper to distinguish the HTTP handler from the