bug 973207 - revert 905460 for nightly crashes r=backout
authorPatrick McManus <mcmanus@ducksong.com>
Mon, 17 Feb 2014 13:53:25 -0500
changeset 169133 4f9f58d41eac
parent 169132 fefba9d06e03
child 169170 6b6450d3fbf0
child 169175 48cd98deecd7
push id26233
push userphilringnalda@gmail.com
push date2014-02-17 23:08 +0000
treeherdermozilla-central@4f9f58d41eac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs973207, 905460
milestone30.0a1
bug 973207 - revert 905460 for nightly crashes r=backout
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnectionInfo.cpp
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpConnectionMgr.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
netwerk/protocol/http/nsHttpPipeline.cpp
netwerk/protocol/http/nsHttpPipeline.h
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -75,22 +75,22 @@ nsHttpConnection::nsHttpConnection()
     , mPriority(nsISupportsPriority::PRIORITY_NORMAL)
     , mReportedSpdy(false)
     , mEverUsedSpdy(false)
     , mLastHttpResponseVersion(NS_HTTP_VERSION_1_1)
     , mTransactionCaps(0)
     , mResponseTimeoutEnabled(false)
     , mTCPKeepaliveConfig(kTCPKeepaliveDisabled)
 {
-    LOG(("Creating nsHttpConnection @%p\n", this));
+    LOG(("Creating nsHttpConnection @%x\n", this));
 }
 
 nsHttpConnection::~nsHttpConnection()
 {
-    LOG(("Destroying nsHttpConnection @%p\n", this));
+    LOG(("Destroying nsHttpConnection @%x\n", this));
 
     ReportDataUsage(false);
     if (!mEverUsedSpdy) {
         LOG(("nsHttpConnection %p performed %d HTTP/1.x transactions\n",
              this, mHttp1xTransactionCount));
         Telemetry::Accumulate(Telemetry::HTTP_REQUEST_PER_CONN,
                               mHttp1xTransactionCount);
     }
@@ -308,17 +308,17 @@ npnComplete:
 
 // called on the socket thread
 nsresult
 nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri)
 {
     nsresult rv;
 
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-    LOG(("nsHttpConnection::Activate [this=%p trans=%p caps=%x]\n",
+    LOG(("nsHttpConnection::Activate [this=%p trans=%x caps=%x]\n",
          this, trans, caps));
 
     if (!trans->IsNullTransaction())
         mExperienced = true;
 
     mTransactionCaps = caps;
     mPriority = pri;
     if (mTransaction && mUsingSpdyVersion)
@@ -1242,17 +1242,17 @@ nsHttpConnection::EndIdleMonitoring()
 
 //-----------------------------------------------------------------------------
 // nsHttpConnection <private>
 //-----------------------------------------------------------------------------
 
 void
 nsHttpConnection::CloseTransaction(nsAHttpTransaction *trans, nsresult reason)
 {
-    LOG(("nsHttpConnection::CloseTransaction[this=%p trans=%p reason=%x]\n",
+    LOG(("nsHttpConnection::CloseTransaction[this=%p trans=%x reason=%x]\n",
         this, trans, reason));
 
     MOZ_ASSERT(trans == mTransaction, "wrong transaction");
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
 
     if (mCurrentBytesRead > mMaxBytesRead)
         mMaxBytesRead = mCurrentBytesRead;
 
@@ -1804,17 +1804,16 @@ nsHttpConnection::OnInputStreamReady(nsI
         // The only read event that is protocol compliant for an idle connection
         // is an EOF, which we check for with CanReuse(). If the data is
         // something else then just ignore it and suspend checking for EOF -
         // our normal timers or protocol stack are the place to deal with
         // any exception logic.
 
         if (!CanReuse()) {
             LOG(("Server initiated close of idle conn %p\n", this));
-            // CloseIdleConnection may delete "this" - return immediately
             gHttpHandler->ConnMgr()->CloseIdleConnection(this);
             return NS_OK;
         }
 
         LOG(("Input data on idle conn %p, but not closing yet\n", this));
         return NS_OK;
     }
 
--- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp
@@ -22,17 +22,17 @@ namespace net {
 
 nsHttpConnectionInfo::nsHttpConnectionInfo(const nsACString &host, int32_t port,
                                            nsProxyInfo* proxyInfo,
                                            bool usingSSL)
     : mProxyInfo(proxyInfo)
     , mUsingSSL(usingSSL)
     , mUsingConnect(false)
 {
-    LOG(("Creating nsHttpConnectionInfo @%p\n", this));
+    LOG(("Creating nsHttpConnectionInfo @%x\n", this));
 
     mUsingHttpProxy = (proxyInfo && proxyInfo->IsHTTP());
 
     if (mUsingHttpProxy) {
         mUsingConnect = mUsingSSL;  // SSL always uses CONNECT
         uint32_t resolveFlags = 0;
         if (NS_SUCCEEDED(mProxyInfo->GetResolveFlags(&resolveFlags)) &&
             resolveFlags & nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL) {
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -36,36 +36,55 @@ extern PRThread *gSocketThread;
 
 namespace mozilla {
 namespace net {
 
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS1(nsHttpConnectionMgr, nsIObserver)
 
+static void
+InsertTransactionSorted(nsTArray<nsHttpTransaction*> &pendingQ, nsHttpTransaction *trans)
+{
+    // insert into queue with smallest valued number first.  search in reverse
+    // order under the assumption that many of the existing transactions will
+    // have the same priority (usually 0).
+
+    for (int32_t i=pendingQ.Length()-1; i>=0; --i) {
+        nsHttpTransaction *t = pendingQ[i];
+        if (trans->Priority() >= t->Priority()) {
+            pendingQ.InsertElementAt(i+1, trans);
+            return;
+        }
+    }
+    pendingQ.InsertElementAt(0, trans);
+}
+
+//-----------------------------------------------------------------------------
+
 nsHttpConnectionMgr::nsHttpConnectionMgr()
     : mReentrantMonitor("nsHttpConnectionMgr.mReentrantMonitor")
     , mMaxConns(0)
     , mMaxPersistConnsPerHost(0)
     , mMaxPersistConnsPerProxy(0)
     , mIsShuttingDown(false)
     , mNumActiveConns(0)
     , mNumIdleConns(0)
     , mNumSpdyActiveConns(0)
     , mNumHalfOpenConns(0)
     , mTimeOfNextWakeUp(UINT64_MAX)
     , mTimeoutTickArmed(false)
     , mTimeoutTickNext(1)
 {
-    LOG(("Creating nsHttpConnectionMgr @%p\n", this));
+    LOG(("Creating nsHttpConnectionMgr @%x\n", this));
 }
 
 nsHttpConnectionMgr::~nsHttpConnectionMgr()
 {
-    LOG(("Destroying nsHttpConnectionMgr @%p\n", this));
+    LOG(("Destroying nsHttpConnectionMgr @%x\n", this));
     if (mTimeoutTick)
         mTimeoutTick->Cancel();
 }
 
 nsresult
 nsHttpConnectionMgr::EnsureSocketThreadTarget()
 {
     nsresult rv;
@@ -153,17 +172,18 @@ nsHttpConnectionMgr::PostEvent(nsConnEve
     EnsureSocketThreadTarget();
 
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     nsresult rv;
     if (!mSocketThreadTarget) {
         NS_WARNING("cannot post event if not initialized");
         rv = NS_ERROR_NOT_INITIALIZED;
-    } else {
+    }
+    else {
         nsRefPtr<nsIRunnable> event = new nsConnEvent(this, handler, iparam, vparam);
         rv = mSocketThreadTarget->Dispatch(event, NS_DISPATCH_NORMAL);
     }
     return rv;
 }
 
 void
 nsHttpConnectionMgr::PruneDeadConnectionsAfter(uint32_t timeInSeconds)
@@ -229,87 +249,85 @@ nsHttpConnectionMgr::Observe(nsISupports
                              const char16_t *data)
 {
     LOG(("nsHttpConnectionMgr::Observe [topic=\"%s\"]\n", topic));
 
     if (0 == strcmp(topic, NS_TIMER_CALLBACK_TOPIC)) {
         nsCOMPtr<nsITimer> timer = do_QueryInterface(subject);
         if (timer == mTimer) {
             PruneDeadConnections();
-        } else if (timer == mTimeoutTick) {
+        }
+        else if (timer == mTimeoutTick) {
             TimeoutTick();
-        } else {
+        }
+        else {
             MOZ_ASSERT(false, "unexpected timer-callback");
             LOG(("Unexpected timer object\n"));
             return NS_ERROR_UNEXPECTED;
         }
     }
 
     return NS_OK;
 }
 
 
 //-----------------------------------------------------------------------------
 
 nsresult
-nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *aTrans, int32_t priority)
+nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *trans, int32_t priority)
 {
-    LOG(("nsHttpConnectionMgr::AddTransaction [trans=%p %d]\n", aTrans, priority));
-
-    nsRefPtr<nsHttpTransaction> trans(aTrans);
+    LOG(("nsHttpConnectionMgr::AddTransaction [trans=%x %d]\n", trans, priority));
+
+    NS_ADDREF(trans);
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgNewTransaction, priority, trans);
-    if (NS_SUCCEEDED(rv)) {
-        trans.forget();
-    }
+    if (NS_FAILED(rv))
+        NS_RELEASE(trans);
     return rv;
 }
 
 nsresult
-nsHttpConnectionMgr::RescheduleTransaction(nsHttpTransaction *aTrans, int32_t priority)
+nsHttpConnectionMgr::RescheduleTransaction(nsHttpTransaction *trans, int32_t priority)
 {
-    LOG(("nsHttpConnectionMgr::RescheduleTransaction [trans=%p %d]\n", aTrans, priority));
-
-    nsRefPtr<nsHttpTransaction> trans(aTrans);
+    LOG(("nsHttpConnectionMgr::RescheduleTransaction [trans=%x %d]\n", trans, priority));
+
+    NS_ADDREF(trans);
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReschedTransaction, priority, trans);
-    if (NS_SUCCEEDED(rv)) {
-        trans.forget();
-    }
+    if (NS_FAILED(rv))
+        NS_RELEASE(trans);
     return rv;
 }
 
 nsresult
-nsHttpConnectionMgr::CancelTransaction(nsHttpTransaction *aTrans, nsresult reason)
+nsHttpConnectionMgr::CancelTransaction(nsHttpTransaction *trans, nsresult reason)
 {
-    LOG(("nsHttpConnectionMgr::CancelTransaction [trans=%p reason=%x]\n", aTrans, reason));
-
-    nsRefPtr<nsHttpTransaction> trans(aTrans);
+    LOG(("nsHttpConnectionMgr::CancelTransaction [trans=%x reason=%x]\n", trans, reason));
+
+    NS_ADDREF(trans);
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgCancelTransaction,
                             static_cast<int32_t>(reason), trans);
-    if (NS_SUCCEEDED(rv)) {
-        trans.forget();
-    }
+    if (NS_FAILED(rv))
+        NS_RELEASE(trans);
     return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::PruneDeadConnections()
 {
     return PostEvent(&nsHttpConnectionMgr::OnMsgPruneDeadConnections);
 }
 
 nsresult
 nsHttpConnectionMgr::DoShiftReloadConnectionCleanup(nsHttpConnectionInfo *aCI)
 {
     nsRefPtr<nsHttpConnectionInfo> connInfo(aCI);
 
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgDoShiftReloadConnectionCleanup,
                             0, connInfo);
-    if (NS_SUCCEEDED(rv)) {
+    if (NS_SUCCEEDED(rv))
         connInfo.forget();
-    }
     return rv;
 }
 
 class SpeculativeConnectArgs
 {
 public:
     SpeculativeConnectArgs() { mOverridesOK = false; }
     virtual ~SpeculativeConnectArgs() {}
@@ -373,42 +391,40 @@ nsHttpConnectionMgr::SpeculativeConnect(
             &args->mParallelSpeculativeConnectLimit);
         overrider->GetIgnoreIdle(&args->mIgnoreIdle);
         overrider->GetIgnorePossibleSpdyConnections(
             &args->mIgnorePossibleSpdyConnections);
     }
 
     nsresult rv =
         PostEvent(&nsHttpConnectionMgr::OnMsgSpeculativeConnect, 0, args);
-    if (NS_SUCCEEDED(rv)) {
+    if (NS_SUCCEEDED(rv))
         args.forget();
-    }
     return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target)
 {
     EnsureSocketThreadTarget();
 
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     NS_IF_ADDREF(*target = mSocketThreadTarget);
     return NS_OK;
 }
 
 nsresult
-nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *aConn)
+nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *conn)
 {
-    LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%p]\n", aConn));
-
-    nsRefPtr<nsHttpConnection> conn(aConn);
+    LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%x]\n", conn));
+
+    NS_ADDREF(conn);
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReclaimConnection, 0, conn);
-    if (NS_SUCCEEDED(rv)) {
-        conn.forget();
-    }
+    if (NS_FAILED(rv))
+        NS_RELEASE(conn);
     return rv;
 }
 
 // A structure used to marshall 2 pointers across the various necessary
 // threads to complete an HTTP upgrade.
 class nsCompleteUpgradeData
 {
 public:
@@ -423,40 +439,38 @@ nsCompleteUpgradeData(nsAHttpConnection 
 nsresult
 nsHttpConnectionMgr::CompleteUpgrade(nsAHttpConnection *aConn,
                                      nsIHttpUpgradeListener *aUpgradeListener)
 {
     nsCompleteUpgradeData *data =
         new nsCompleteUpgradeData(aConn, aUpgradeListener);
     nsresult rv;
     rv = PostEvent(&nsHttpConnectionMgr::OnMsgCompleteUpgrade, 0, data);
-    if (NS_FAILED(rv)) {
+    if (NS_FAILED(rv))
         delete data;
-    }
     return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::UpdateParam(nsParamName name, uint16_t value)
 {
     uint32_t param = (uint32_t(name) << 16) | uint32_t(value);
     return PostEvent(&nsHttpConnectionMgr::OnMsgUpdateParam, 0,
                      (void *)(uintptr_t) param);
 }
 
 nsresult
-nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *aCI)
+nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *ci)
 {
-    LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", aCI->HashKey().get()));
-
-    nsRefPtr<nsHttpConnectionInfo> ci(aCI);
+    LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", ci->HashKey().get()));
+
+    NS_ADDREF(ci);
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, ci);
-    if (NS_SUCCEEDED(rv)) {
-        ci.forget();
-    }
+    if (NS_FAILED(rv))
+        NS_RELEASE(ci);
     return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::ProcessPendingQ()
 {
     LOG(("nsHttpConnectionMgr::ProcessPendingQ [All CI]\n"));
     return PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, nullptr);
@@ -474,19 +488,18 @@ nsresult
 nsHttpConnectionMgr::UpdateRequestTokenBucket(EventTokenBucket *aBucket)
 {
     nsRefPtr<EventTokenBucket> bucket(aBucket);
 
     // Call From main thread when a new EventTokenBucket has been made in order
     // to post the new value to the socket thread.
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgUpdateRequestTokenBucket,
                             0, bucket.get());
-    if (NS_SUCCEEDED(rv)) {
+    if (NS_SUCCEEDED(rv))
         bucket.forget();
-    }
     return rv;
 }
 
 // Given a nsHttpConnectionInfo find the connection entry object that
 // contains either the nshttpconnection or nshttptransaction parameter.
 // Normally this is done by the hashkey lookup of connectioninfo,
 // but if spdy coalescing is in play it might be found in a redirected
 // entry
@@ -530,29 +543,28 @@ nsHttpConnectionMgr::LookupConnectionEnt
 }
 
 nsresult
 nsHttpConnectionMgr::CloseIdleConnection(nsHttpConnection *conn)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::CloseIdleConnection %p conn=%p",
          this, conn));
-    nsRefPtr<nsHttpConnection> deleteProtector(conn);
 
     if (!conn->ConnectionInfo())
         return NS_ERROR_UNEXPECTED;
 
     nsConnectionEntry *ent = LookupConnectionEntry(conn->ConnectionInfo(),
                                                    conn, nullptr);
 
     if (!ent || !ent->mIdleConns.RemoveElement(conn))
         return NS_ERROR_UNEXPECTED;
 
     conn->Close(NS_ERROR_ABORT);
-    conn = nullptr;
+    NS_RELEASE(conn);
     mNumIdleConns--;
     ConditionallyStopPruneDeadConnectionsTimer();
     return NS_OK;
 }
 
 // This function lets a connection, after completing the NPN phase,
 // report whether or not it is using spdy through the usingSpdy
 // argument. It would not be necessary if NPN were driven out of
@@ -836,20 +848,20 @@ nsHttpConnectionMgr::PurgeExcessIdleConn
 {
     nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
 
     while (self->mNumIdleConns + self->mNumActiveConns + 1 >= self->mMaxConns) {
         if (!ent->mIdleConns.Length()) {
             // There are no idle conns left in this connection entry
             return PL_DHASH_NEXT;
         }
-        nsRefPtr<nsHttpConnection> conn(ent->mIdleConns[0]);
+        nsHttpConnection *conn = ent->mIdleConns[0];
         ent->mIdleConns.RemoveElementAt(0);
         conn->Close(NS_ERROR_ABORT);
-        conn = nullptr;
+        NS_RELEASE(conn);
         self->mNumIdleConns--;
         self->ConditionallyStopPruneDeadConnectionsTimer();
     }
     return PL_DHASH_STOP;
 }
 
 // If the global number of connections is preventing the opening of
 // new connections to a host without idle connections, then
@@ -885,38 +897,39 @@ nsHttpConnectionMgr::PruneDeadConnection
 
     LOG(("  pruning [ci=%s]\n", ent->mConnInfo->HashKey().get()));
 
     // Find out how long it will take for next idle connection to not be reusable
     // anymore.
     uint32_t timeToNextExpire = UINT32_MAX;
     int32_t count = ent->mIdleConns.Length();
     if (count > 0) {
-        for (int32_t i = count - 1; i >= 0; --i) {
-            if (!ent->mIdleConns[i]->CanReuse()) {
-                nsRefPtr<nsHttpConnection> conn(ent->mIdleConns[i]);
+        for (int32_t i=count-1; i>=0; --i) {
+            nsHttpConnection *conn = ent->mIdleConns[i];
+            if (!conn->CanReuse()) {
                 ent->mIdleConns.RemoveElementAt(i);
                 conn->Close(NS_ERROR_ABORT);
+                NS_RELEASE(conn);
                 self->mNumIdleConns--;
             } else {
-                timeToNextExpire = std::min(timeToNextExpire,
-                                            ent->mIdleConns[i]->TimeToLive());
+                timeToNextExpire = std::min(timeToNextExpire, conn->TimeToLive());
             }
         }
     }
 
     if (ent->mUsingSpdy) {
         for (uint32_t index = 0; index < ent->mActiveConns.Length(); ++index) {
             nsHttpConnection *conn = ent->mActiveConns[index];
             if (conn->UsingSpdy()) {
                 if (!conn->CanReuse()) {
                     // marking it dont reuse will create an active tear down if
                     // the spdy session is idle.
                     conn->DontReuse();
-                } else {
+                }
+                else {
                     timeToNextExpire = std::min(timeToNextExpire,
                                               conn->TimeToLive());
                 }
             }
         }
     }
 
     // If time to next expire found is shorter than time to next wake-up, we need to
@@ -962,42 +975,52 @@ nsHttpConnectionMgr::PruneDeadConnection
 
 PLDHashOperator
 nsHttpConnectionMgr::ShutdownPassCB(const nsACString &key,
                                     nsAutoPtr<nsConnectionEntry> &ent,
                                     void *closure)
 {
     nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
 
-    // close all active connections and release list references
+    nsHttpTransaction *trans;
+    nsHttpConnection *conn;
+
+    // close all active connections
     while (ent->mActiveConns.Length()) {
-        nsRefPtr<nsHttpConnection> conn(ent->mActiveConns[0]);
+        conn = ent->mActiveConns[0];
 
         ent->mActiveConns.RemoveElementAt(0);
         self->DecrementActiveConnCount(conn);
 
         conn->Close(NS_ERROR_ABORT);
+        NS_RELEASE(conn);
     }
 
-    // close all idle connections and release list references
+    // close all idle connections
     while (ent->mIdleConns.Length()) {
-        nsRefPtr<nsHttpConnection> conn(ent->mIdleConns[0]);
+        conn = ent->mIdleConns[0];
+
         ent->mIdleConns.RemoveElementAt(0);
         self->mNumIdleConns--;
+
         conn->Close(NS_ERROR_ABORT);
+        NS_RELEASE(conn);
     }
     // If all idle connections are removed,
     // we can stop pruning dead connections.
     self->ConditionallyStopPruneDeadConnectionsTimer();
 
-    // close all pending transactions and release list references
+    // close all pending transactions
     while (ent->mPendingQ.Length()) {
-        nsRefPtr<nsHttpTransaction> trans(ent->mPendingQ[0]);
+        trans = ent->mPendingQ[0];
+
         ent->mPendingQ.RemoveElementAt(0);
+
         trans->Close(NS_ERROR_ABORT);
+        NS_RELEASE(trans);
     }
 
     // close all half open tcp connections
     for (int32_t i = ((int32_t) ent->mHalfOpens.Length()) - 1; i >= 0; i--)
         ent->mHalfOpens[i]->Abandon();
 
     return PL_DHASH_REMOVE;
 }
@@ -1042,16 +1065,17 @@ nsHttpConnectionMgr::ProcessPendingQForE
             if (NS_SUCCEEDED(rv))
                 LOG(("  dispatching pending transaction...\n"));
             else
                 LOG(("  removing pending transaction based on "
                      "TryDispatchTransaction returning hard error %x\n", rv));
 
             if (ent->mPendingQ.RemoveElement(trans)) {
                 dispatchedSuccessfully = true;
+                NS_RELEASE(trans);
                 continue; // dont ++i as we just made the array shorter
             }
 
             LOG(("  transaction not found in pending queue\n"));
         }
 
         if (dispatchedSuccessfully && !considerAll)
             break;
@@ -1234,20 +1258,21 @@ nsHttpConnectionMgr::AtActiveConnectionL
 }
 
 void
 nsHttpConnectionMgr::ClosePersistentConnections(nsConnectionEntry *ent)
 {
     LOG(("nsHttpConnectionMgr::ClosePersistentConnections [ci=%s]\n",
          ent->mConnInfo->HashKey().get()));
     while (ent->mIdleConns.Length()) {
-        nsRefPtr<nsHttpConnection> conn(ent->mIdleConns[0]);
+        nsHttpConnection *conn = ent->mIdleConns[0];
         ent->mIdleConns.RemoveElementAt(0);
         mNumIdleConns--;
         conn->Close(NS_ERROR_ABORT);
+        NS_RELEASE(conn);
     }
 
     int32_t activeCount = ent->mActiveConns.Length();
     for (int32_t i=0; i < activeCount; i++)
         ent->mActiveConns[i]->DontReuse();
 }
 
 PLDHashOperator
@@ -1450,19 +1475,18 @@ nsHttpConnectionMgr::AddToShortestPipeli
         }
     }
 
     if (!bestConn)
         return false;
 
     activeTrans = bestConn->Transaction();
     nsresult rv = activeTrans->AddTransaction(trans);
-    if (NS_FAILED(rv)) {
+    if (NS_FAILED(rv))
         return false;
-    }
 
     LOG(("   scheduling trans %p on pipeline at position %d\n",
          trans, trans->PipelinePosition()));
 
     if ((ent->PipelineState() == PS_YELLOW) && (trans->PipelinePosition() > 1))
         ent->SetYellowConnection(bestConn);
 
     if (!trans->GetPendingTime().IsNull()) {
@@ -1558,17 +1582,17 @@ nsHttpConnectionMgr::TryDispatchTransact
     // step 0
     // look for existing spdy connection - that's always best because it is
     // essentially pipelining without head of line blocking
 
     if (!(caps & NS_HTTP_DISALLOW_SPDY) && gHttpHandler->IsSpdyEnabled()) {
         nsRefPtr<nsHttpConnection> conn = GetSpdyPreferredConn(ent);
         if (conn) {
             if ((caps & NS_HTTP_ALLOW_KEEPALIVE) || !conn->IsExperienced()) {
-                LOG(("   dispatch to spdy: [conn=%p]\n", conn.get()));
+                LOG(("   dispatch to spdy: [conn=%x]\n", conn.get()));
                 trans->RemoveDispatchedAsBlocking();  /* just in case */
                 DispatchTransaction(ent, trans, conn);
                 return NS_OK;
             }
             unusedSpdyPersistentConnection = conn;
         }
     }
 
@@ -1584,17 +1608,18 @@ nsHttpConnectionMgr::TryDispatchTransact
                 if (NS_SUCCEEDED(loadGroupCI->GetBlockingTransactionCount(&blockers)) &&
                     blockers) {
                     // need to wait for blockers to clear
                     LOG(("   blocked by load group: [blockers=%d]\n", blockers));
                     return NS_ERROR_NOT_AVAILABLE;
                 }
             }
         }
-    } else {
+    }
+    else {
         // Mark the transaction and its load group as blocking right now to prevent
         // other transactions from being reordered in the queue due to slow syns.
         trans->DispatchedAsBlocking();
     }
 
     // step 1
     // If connection pressure, then we want to favor pipelining of any kind
     if (IsUnderPressure(ent, classification) && !attemptedOptimisticPipeline) {
@@ -1626,25 +1651,28 @@ nsHttpConnectionMgr::TryDispatchTransact
     // step 2
     // consider an idle persistent connection
     if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
         nsRefPtr<nsHttpConnection> conn;
         while (!conn && (ent->mIdleConns.Length() > 0)) {
             conn = ent->mIdleConns[0];
             ent->mIdleConns.RemoveElementAt(0);
             mNumIdleConns--;
+            nsHttpConnection *temp = conn;
+            NS_RELEASE(temp);
 
             // we check if the connection can be reused before even checking if
             // it is a "matching" connection.
             if (!conn->CanReuse()) {
-                LOG(("   dropping stale connection: [conn=%p]\n", conn.get()));
+                LOG(("   dropping stale connection: [conn=%x]\n", conn.get()));
                 conn->Close(NS_ERROR_ABORT);
                 conn = nullptr;
-            } else {
-                LOG(("   reusing connection [conn=%p]\n", conn.get()));
+            }
+            else {
+                LOG(("   reusing connection [conn=%x]\n", conn.get()));
                 conn->EndIdleMonitoring();
             }
 
             // If there are no idle connections left at all, we need to make
             // sure that we are not pruning dead connections anymore.
             ConditionallyStopPruneDeadConnectionsTimer();
         }
         if (conn) {
@@ -1709,17 +1737,17 @@ nsHttpConnectionMgr::DispatchTransaction
                                          nsHttpTransaction *trans,
                                          nsHttpConnection *conn)
 {
     uint32_t caps = trans->Caps();
     int32_t priority = trans->Priority();
     nsresult rv;
 
     LOG(("nsHttpConnectionMgr::DispatchTransaction "
-         "[ci=%s trans=%p caps=%x conn=%p priority=%d]\n",
+         "[ci=%s trans=%x caps=%x conn=%x priority=%d]\n",
          ent->mConnInfo->HashKey().get(), trans, caps, conn, priority));
 
     // It is possible for a rate-paced transaction to be dispatched independent
     // of the token bucket when the amount of parallelization has changed or
     // when a muxed connection (e.g. spdy or pipelines) becomes available.
     trans->CancelPacing(NS_OK);
 
     if (conn->UsingSpdy()) {
@@ -1769,17 +1797,17 @@ nsHttpConnectionMgr::DispatchAbstractTra
                                                  nsAHttpTransaction *aTrans,
                                                  uint32_t caps,
                                                  nsHttpConnection *conn,
                                                  int32_t priority)
 {
     MOZ_ASSERT(!conn->UsingSpdy(),
                "Spdy Must Not Use DispatchAbstractTransaction");
     LOG(("nsHttpConnectionMgr::DispatchAbstractTransaction "
-         "[ci=%s trans=%p caps=%x conn=%p]\n",
+         "[ci=%s trans=%x caps=%x conn=%x]\n",
          ent->mConnInfo->HashKey().get(), aTrans, caps, conn));
 
     /* Use pipeline datastructure even if connection does not currently qualify
        to pipeline this transaction because a different pipeline-eligible
        transaction might be placed on the active connection. Make an exception
        for CLASS_SOLO as that connection will never pipeline until it goes
        quiescent */
 
@@ -1787,40 +1815,42 @@ nsHttpConnectionMgr::DispatchAbstractTra
     nsresult rv;
     if (conn->Classification() != nsAHttpTransaction::CLASS_SOLO) {
         LOG(("   using pipeline datastructure.\n"));
         nsRefPtr<nsHttpPipeline> pipeline;
         rv = BuildPipeline(ent, aTrans, getter_AddRefs(pipeline));
         if (!NS_SUCCEEDED(rv))
             return rv;
         transaction = pipeline;
-    } else {
+    }
+    else {
         LOG(("   not using pipeline datastructure due to class solo.\n"));
         transaction = aTrans;
     }
 
     nsRefPtr<nsConnectionHandle> handle = new nsConnectionHandle(conn);
 
     // give the transaction the indirect reference to the connection.
     transaction->SetConnection(handle);
 
     rv = conn->Activate(transaction, caps, priority);
     if (NS_FAILED(rv)) {
         LOG(("  conn->Activate failed [rv=%x]\n", rv));
-        nsRefPtr<nsHttpConnection> deleteProtector(conn);
         ent->mActiveConns.RemoveElement(conn);
         if (conn == ent->mYellowConnection)
             ent->OnYellowComplete();
         DecrementActiveConnCount(conn);
         ConditionallyStopTimeoutTick();
 
         // sever back references to connection, and do so without triggering
         // a call to ReclaimConnection ;-)
         transaction->SetConnection(nullptr);
-        handle->Reset();
+        NS_RELEASE(handle->mConn);
+        // destroy the connection
+        NS_RELEASE(conn);
     }
 
     // As transaction goes out of scope it will drop the last refernece to the
     // pipeline if activation failed, in which case this will destroy
     // the pipeline, which will cause each the transactions owned by the
     // pipeline to be restarted.
 
     return rv;
@@ -1836,17 +1866,17 @@ nsHttpConnectionMgr::BuildPipeline(nsCon
     /* form a pipeline here even if nothing is pending so that we
        can stream-feed it as new transactions arrive */
 
     /* the first transaction can go in unconditionally - 1 transaction
        on a nsHttpPipeline object is not a real HTTP pipeline */
 
     nsRefPtr<nsHttpPipeline> pipeline = new nsHttpPipeline();
     pipeline->AddTransaction(firstTrans);
-    pipeline.forget(result);
+    NS_ADDREF(*result = pipeline);
     return NS_OK;
 }
 
 void
 nsHttpConnectionMgr::ReportProxyTelemetry(nsConnectionEntry *ent)
 {
     enum { PROXY_NONE = 1, PROXY_HTTP = 2, PROXY_SOCKS = 3 };
 
@@ -1917,30 +1947,33 @@ nsHttpConnectionMgr::ProcessNewTransacti
     if (NS_SUCCEEDED(rv)) {
         LOG(("  ProcessNewTransaction Dispatch Immediately trans=%p\n", trans));
         return rv;
     }
 
     if (rv == NS_ERROR_NOT_AVAILABLE) {
         LOG(("  adding transaction to pending queue "
              "[trans=%p pending-count=%u]\n",
-             trans, ent->mPendingQ.Length() + 1));
+             trans, ent->mPendingQ.Length()+1));
         // put this transaction on the pending queue...
         InsertTransactionSorted(ent->mPendingQ, trans);
+        NS_ADDREF(trans);
         return NS_OK;
     }
 
     LOG(("  ProcessNewTransaction Hard Error trans=%p rv=%x\n", trans, rv));
     return rv;
 }
 
+
 void
 nsHttpConnectionMgr::AddActiveConn(nsHttpConnection *conn,
                                    nsConnectionEntry *ent)
 {
+    NS_ADDREF(conn);
     ent->mActiveConns.AppendElement(conn);
     mNumActiveConns++;
     ActivateTimeoutTick();
 }
 
 void
 nsHttpConnectionMgr::DecrementActiveConnCount(nsHttpConnection *conn)
 {
@@ -1990,17 +2023,17 @@ nsHttpConnectionMgr::CreateTransport(nsC
 
 void
 nsHttpConnectionMgr::ProcessSpdyPendingQ(nsConnectionEntry *ent)
 {
     nsHttpConnection *conn = GetSpdyPreferredConn(ent);
     if (!conn || !conn->CanDirectlyActivate())
         return;
 
-    nsTArray<nsRefPtr<nsHttpTransaction> > leftovers;
+    nsTArray<nsHttpTransaction*> leftovers;
     uint32_t index;
 
     // Dispatch all the transactions we can
     for (index = 0;
          index < ent->mPendingQ.Length() && conn->CanDirectlyActivate();
          ++index) {
         nsHttpTransaction *trans = ent->mPendingQ[index];
 
@@ -2011,25 +2044,27 @@ nsHttpConnectionMgr::ProcessSpdyPendingQ
         }
 
         nsresult rv = DispatchTransaction(ent, trans, conn);
         if (NS_FAILED(rv)) {
             // this cannot happen, but if due to some bug it does then
             // close the transaction
             MOZ_ASSERT(false, "Dispatch SPDY Transaction");
             LOG(("ProcessSpdyPendingQ Dispatch Transaction failed trans=%p\n",
-                 trans));
+                    trans));
             trans->Close(rv);
         }
+        NS_RELEASE(trans);
     }
 
     // Slurp up the rest of the pending queue into our leftovers bucket (we
     // might have some left if conn->CanDirectlyActivate returned false)
     for (; index < ent->mPendingQ.Length(); ++index) {
-        leftovers.AppendElement(ent->mPendingQ[index]);
+        nsHttpTransaction *trans = ent->mPendingQ[index];
+        leftovers.AppendElement(trans);
     }
 
     // Put the leftovers back in the pending queue and get rid of the
     // transactions we dispatched
     leftovers.SwapElements(ent->mPendingQ);
     leftovers.Clear();
 }
 
@@ -2115,74 +2150,75 @@ nsHttpConnectionMgr::OnMsgShutdownConfir
     *shutdown = true;
 }
 
 void
 nsHttpConnectionMgr::OnMsgNewTransaction(int32_t priority, void *param)
 {
     LOG(("nsHttpConnectionMgr::OnMsgNewTransaction [trans=%p]\n", param));
 
-    nsRefPtr<nsHttpTransaction> trans =
-        dont_AddRef(static_cast<nsHttpTransaction *>(param));
+    nsHttpTransaction *trans = (nsHttpTransaction *) param;
     trans->SetPriority(priority);
     nsresult rv = ProcessNewTransaction(trans);
-    if (NS_FAILED(rv)) {
+    if (NS_FAILED(rv))
         trans->Close(rv); // for whatever its worth
-    }
+    NS_RELEASE(trans);
 }
 
 void
 nsHttpConnectionMgr::OnMsgReschedTransaction(int32_t priority, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::OnMsgReschedTransaction [trans=%p]\n", param));
 
-    nsRefPtr<nsHttpTransaction> trans =
-        dont_AddRef(static_cast<nsHttpTransaction *>(param));
+    nsHttpTransaction *trans = (nsHttpTransaction *) param;
     trans->SetPriority(priority);
 
     nsConnectionEntry *ent = LookupConnectionEntry(trans->ConnectionInfo(),
                                                    nullptr, trans);
 
     if (ent) {
         int32_t index = ent->mPendingQ.IndexOf(trans);
         if (index >= 0) {
             ent->mPendingQ.RemoveElementAt(index);
             InsertTransactionSorted(ent->mPendingQ, trans);
         }
     }
+
+    NS_RELEASE(trans);
 }
 
 void
 nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]\n", param));
 
     nsresult closeCode = static_cast<nsresult>(reason);
-    nsRefPtr<nsHttpTransaction> trans =
-        dont_AddRef(static_cast<nsHttpTransaction *>(param));
+    nsHttpTransaction *trans = (nsHttpTransaction *) param;
     //
     // if the transaction owns a connection and the transaction is not done,
     // then ask the connection to close the transaction.  otherwise, close the
     // transaction directly (removing it from the pending queue first).
     //
     nsAHttpConnection *conn = trans->Connection();
     if (conn && !trans->IsDone()) {
         conn->CloseTransaction(trans, closeCode);
     } else {
         nsConnectionEntry *ent =
             LookupConnectionEntry(trans->ConnectionInfo(), nullptr, trans);
 
         if (ent) {
             int32_t index = ent->mPendingQ.IndexOf(trans);
             if (index >= 0) {
                 LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]"
-                     " found in pending queue\n", trans.get()));
+                     " found in pending queue\n", trans));
                 ent->mPendingQ.RemoveElementAt(index);
+                nsHttpTransaction *temp = trans;
+                NS_RELEASE(temp); // b/c NS_RELEASE nulls its argument!
             }
         }
         trans->Close(closeCode);
 
         // Cancel is a pretty strong signal that things might be hanging
         // so we want to cancel any null transactions related to this connection
         // entry. They are just optimizations, but they aren't hooked up to
         // anything that might get canceled from the rest of gecko, so best
@@ -2191,29 +2227,29 @@ nsHttpConnectionMgr::OnMsgCancelTransact
         for (uint32_t index = 0;
              ent && (index < ent->mActiveConns.Length());
              ++index) {
             nsHttpConnection *activeConn = ent->mActiveConns[index];
             nsAHttpTransaction *liveTransaction = activeConn->Transaction();
             if (liveTransaction && liveTransaction->IsNullTransaction()) {
                 LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p] "
                      "also canceling Null Transaction %p on conn %p\n",
-                     trans.get(), liveTransaction, activeConn));
+                     trans, liveTransaction, activeConn));
                 activeConn->CloseTransaction(liveTransaction, closeCode);
             }
         }
     }
+    NS_RELEASE(trans);
 }
 
 void
 nsHttpConnectionMgr::OnMsgProcessPendingQ(int32_t, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-    nsRefPtr<nsHttpConnectionInfo> ci =
-        dont_AddRef(static_cast<nsHttpConnectionInfo *>(param));
+    nsHttpConnectionInfo *ci = (nsHttpConnectionInfo *) param;
 
     if (!ci) {
         LOG(("nsHttpConnectionMgr::OnMsgProcessPendingQ [ci=nullptr]\n"));
         // Try and dispatch everything
         mCT.Enumerate(ProcessAllTransactionsCB, this);
         return;
     }
 
@@ -2222,16 +2258,18 @@ nsHttpConnectionMgr::OnMsgProcessPending
 
     // start by processing the queue identified by the given connection info.
     nsConnectionEntry *ent = mCT.Get(ci->HashKey());
     if (!(ent && ProcessPendingQForEntry(ent, false))) {
         // if we reach here, it means that we couldn't dispatch a transaction
         // for the specified connection info.  walk the connection table...
         mCT.Enumerate(ProcessOneTransactionCB, this);
     }
+
+    NS_RELEASE(ci);
 }
 
 void
 nsHttpConnectionMgr::OnMsgPruneDeadConnections(int32_t, void *)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::OnMsgPruneDeadConnections\n"));
 
@@ -2259,36 +2297,36 @@ nsHttpConnectionMgr::OnMsgDoShiftReloadC
 }
 
 void
 nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection [conn=%p]\n", param));
 
-    nsRefPtr<nsHttpConnection> conn =
-        dont_AddRef(static_cast<nsHttpConnection *>(param));
+    nsHttpConnection *conn = (nsHttpConnection *) param;
 
     //
     // 1) remove the connection from the active list
     // 2) if keep-alive, add connection to idle list
     // 3) post event to process the pending transaction queue
     //
 
     nsConnectionEntry *ent = LookupConnectionEntry(conn->ConnectionInfo(),
                                                    conn, nullptr);
-    nsRefPtr<nsHttpConnectionInfo> ci;
+    nsHttpConnectionInfo *ci = nullptr;
 
     if (!ent) {
         // this should never happen
         LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection ent == null\n"));
         MOZ_ASSERT(false, "no connection entry");
-        ci = conn->ConnectionInfo();
-    } else {
-        ci = ent->mConnInfo;
+        NS_ADDREF(ci = conn->ConnectionInfo());
+    }
+    else {
+        NS_ADDREF(ci = ent->mConnInfo);
 
         // If the connection is in the active list, remove that entry
         // and the reference held by the mActiveConns list.
         // This is never the final reference on conn as the event context
         // is also holding one that is released at the end of this function.
 
         if (ent->mUsingSpdy) {
             // Spdy connections aren't reused in the traditional HTTP way in
@@ -2298,17 +2336,18 @@ nsHttpConnectionMgr::OnMsgReclaimConnect
             // is really complete and is meant to be shut down and not
             // reused.
             conn->DontReuse();
         }
 
         if (ent->mActiveConns.RemoveElement(conn)) {
             if (conn == ent->mYellowConnection)
                 ent->OnYellowComplete();
-
+            nsHttpConnection *temp = conn;
+            NS_RELEASE(temp);
             DecrementActiveConnCount(conn);
             ConditionallyStopTimeoutTick();
         }
 
         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
@@ -2319,33 +2358,36 @@ nsHttpConnectionMgr::OnMsgReclaimConnect
 
             uint32_t 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.InsertElementAt(idx, conn);
             mNumIdleConns++;
             conn->BeginIdleMonitoring();
 
             // If the added connection was first idle connection or has shortest
             // time to live among the watched connections, pruning dead
             // connections needs to be done when it can't be reused anymore.
             uint32_t timeToLive = conn->TimeToLive();
             if(!mTimer || NowInSeconds() + timeToLive < mTimeOfNextWakeUp)
                 PruneDeadConnectionsAfter(timeToLive);
-        } else {
+        }
+        else {
             LOG(("  connection cannot be reused; closing connection\n"));
             conn->Close(NS_ERROR_ABORT);
         }
     }
 
-    OnMsgProcessPendingQ(0, ci.forget().get()); // releases |ci ref|
+    OnMsgProcessPendingQ(0, ci); // releases |ci|
+    NS_RELEASE(conn);
 }
 
 void
 nsHttpConnectionMgr::OnMsgCompleteUpgrade(int32_t, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     nsCompleteUpgradeData *data = (nsCompleteUpgradeData *) param;
     LOG(("nsHttpConnectionMgr::OnMsgCompleteUpgrade "
@@ -2398,16 +2440,18 @@ nsHttpConnectionMgr::OnMsgUpdateParam(in
     }
 }
 
 // nsHttpConnectionMgr::nsConnectionEntry
 nsHttpConnectionMgr::nsConnectionEntry::~nsConnectionEntry()
 {
     if (mSpdyPreferred)
         gHttpHandler->ConnMgr()->RemoveSpdyPreferredEnt(mCoalescingKey);
+
+    NS_RELEASE(mConnInfo);
 }
 
 void
 nsHttpConnectionMgr::OnMsgProcessFeedback(int32_t, void *param)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     nsHttpPipelineFeedback *fb = (nsHttpPipelineFeedback *)param;
 
@@ -2520,43 +2564,24 @@ nsHttpConnectionMgr::TimeoutTickCB(const
         }
     }
     if (ent->mHalfOpens.Length()) {
         self->mTimeoutTickNext = 1;
     }
     return PL_DHASH_NEXT;
 }
 
-void
-nsHttpConnectionMgr::
-InsertTransactionSorted(nsTArray<nsRefPtr<nsHttpTransaction> > &pendingQ,
-                        nsHttpTransaction *trans)
-{
-    // Insert into queue with smallest valued number first. Search in reverse
-    // order under the assumption that many of the existing transactions will
-    // have the same priority (usually 0).
-    // List holds a reference on all members of mPendingQ
-
-    for (int32_t i = pendingQ.Length() - 1; i >= 0; --i) {
-        nsHttpTransaction *t = pendingQ[i];
-        if (trans->Priority() >= t->Priority()) {
-            pendingQ.InsertElementAt(i + 1, trans);
-            return;
-        }
-    }
-    pendingQ.InsertElementAt(0, trans);
-}
-
 //-----------------------------------------------------------------------------
 // nsHttpConnectionMgr::nsConnectionHandle
 
 nsHttpConnectionMgr::nsConnectionHandle::~nsConnectionHandle()
 {
     if (mConn) {
         gHttpHandler->ReclaimConnection(mConn);
+        NS_RELEASE(mConn);
     }
 }
 
 NS_IMPL_ISUPPORTS0(nsHttpConnectionMgr::nsConnectionHandle)
 
 nsHttpConnectionMgr::nsConnectionEntry *
 nsHttpConnectionMgr::GetOrCreateConnectionEntry(nsHttpConnectionInfo *ci)
 {
@@ -2627,17 +2652,18 @@ nsHttpConnectionMgr::OnMsgSpeculativeCon
     }
 
     if (mNumHalfOpenConns < parallelSpeculativeConnectLimit &&
         ((ignoreIdle && (ent->mIdleConns.Length() < parallelSpeculativeConnectLimit)) ||
          !ent->mIdleConns.Length()) &&
         !RestrictConnections(ent, ignorePossibleSpdyConnections) &&
         !AtActiveConnectionLimit(ent, args->mTrans->Caps())) {
         CreateTransport(ent, args->mTrans, args->mTrans->Caps(), true);
-    } else {
+    }
+    else {
         LOG(("  Transport not created due to existing connection count\n"));
     }
 }
 
 bool
 nsHttpConnectionMgr::nsConnectionHandle::IsPersistent()
 {
     return mConn->IsPersistent();
@@ -2977,17 +3003,18 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
 
         if (NS_SUCCEEDED(mSocketTransport->GetPeerAddr(&peeraddr)))
             mEnt->RecordIPFamilyPreference(peeraddr.raw.family);
 
         // The nsHttpConnection object now owns these streams and sockets
         mStreamOut = nullptr;
         mStreamIn = nullptr;
         mSocketTransport = nullptr;
-    } else {
+    }
+    else {
         TimeDuration rtt = TimeStamp::Now() - mBackupSynStarted;
         rv = conn->Init(mEnt->mConnInfo,
                         gHttpHandler->ConnMgr()->mMaxRequestDelay,
                         mBackupTransport, mBackupStreamIn, mBackupStreamOut,
                         callbacks,
                         PR_MillisecondsToInterval(
                           static_cast<uint32_t>(rtt.ToMilliseconds())));
 
@@ -3010,21 +3037,22 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
     // from counter of actual connections used for checking limits.
     mHasConnected = true;
 
     // if this is still in the pending list, remove it and dispatch it
     index = mEnt->mPendingQ.IndexOf(mTransaction);
     if (index != -1) {
         MOZ_ASSERT(!mSpeculative,
                    "Speculative Half Open found mTranscation");
-        nsRefPtr<nsHttpTransaction> temp(mEnt->mPendingQ[index]);
+        nsRefPtr<nsHttpTransaction> temp = dont_AddRef(mEnt->mPendingQ[index]);
         mEnt->mPendingQ.RemoveElementAt(index);
         gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt);
         rv = gHttpHandler->ConnMgr()->DispatchTransaction(mEnt, temp, conn);
-    } else {
+    }
+    else {
         // this transaction was dispatched off the pending q before all the
         // sockets established themselves.
 
         // We need to establish a small non-zero idle timeout so the connection
         // mgr perceives this socket as suitable for persistent connection reuse
         const PRIntervalTime k5Sec = PR_SecondsToInterval(5);
         if (k5Sec < gHttpHandler->IdleTimeout())
             conn->SetIdleTimeout(k5Sec);
@@ -3049,17 +3077,18 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
                 new NullHttpTransaction(mEnt->mConnInfo,
                                         callbacks,
                                         mCaps & ~NS_HTTP_ALLOW_PIPELINING);
 
             gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt);
             conn->Classify(nsAHttpTransaction::CLASS_SOLO);
             rv = gHttpHandler->ConnMgr()->
                 DispatchAbstractTransaction(mEnt, trans, mCaps, conn, 0);
-        } else {
+        }
+        else {
             // otherwise just put this in the persistent connection pool
             LOG(("nsHalfOpenSocket::OnOutputStreamReady no transaction match "
                  "returning conn %p to pool\n", conn.get()));
             nsRefPtr<nsHttpConnection> copy(conn);
             // forget() to effectively addref because onmsg*() will drop a ref
             gHttpHandler->ConnMgr()->OnMsgReclaimConnection(
                 0, conn.forget().get());
         }
@@ -3203,16 +3232,17 @@ nsConnectionEntry::nsConnectionEntry(nsH
     , mPipeliningPenalty(0)
     , mSpdyCWND(0)
     , mUsingSpdy(false)
     , mTestedSpdy(false)
     , mSpdyPreferred(false)
     , mPreferIPv4(false)
     , mPreferIPv6(false)
 {
+    NS_ADDREF(mConnInfo);
     if (gHttpHandler->GetPipelineAggressive()) {
         mGreenDepth = kPipelineUnlimited;
         mPipelineState = PS_GREEN;
     }
     mInitialGreenDepth = mGreenDepth;
     memset(mPipeliningClassPenalty, 0, sizeof(int16_t) * nsAHttpTransaction::CLASS_MAX);
 }
 
@@ -3328,17 +3358,18 @@ nsConnectionEntry::OnPipelineFeedbackInf
         mPipeliningPenalty = std::min(mPipeliningPenalty, kPenalty);
         mPipeliningClassPenalty[classification] =
           std::min(mPipeliningClassPenalty[classification], kPenalty);
 
         LOG(("Assessing red penalty to %s class %d for event %d. "
              "Penalty now %d, throttle[%d] = %d\n", mConnInfo->Host(),
              classification, info, mPipeliningPenalty, classification,
              mPipeliningClassPenalty[classification]));
-    } else {
+    }
+    else {
         // hand out credits for neutral and good events such as
         // "headers look ok" events
 
         mPipeliningPenalty = std::max(mPipeliningPenalty - 1, 0);
         mPipeliningClassPenalty[classification] = std::max(mPipeliningClassPenalty[classification] - 1, 0);
     }
 
     if (mPipelineState == PS_RED && !mPipeliningPenalty)
@@ -3363,17 +3394,18 @@ void
 nsHttpConnectionMgr::
 nsConnectionEntry::OnYellowComplete()
 {
     if (mPipelineState == PS_YELLOW) {
         if (mYellowGoodEvents && !mYellowBadEvents) {
             LOG(("transition %s to green\n", mConnInfo->Host()));
             mPipelineState = PS_GREEN;
             mGreenDepth = mInitialGreenDepth;
-        } else {
+        }
+        else {
             // The purpose of the yellow state is to witness at least
             // one successful pipelined transaction without seeing any
             // kind of negative feedback before opening the flood gates.
             // If we haven't confirmed that, then transfer back to red.
             LOG(("transition %s to red from yellow return\n",
                  mConnInfo->Host()));
             mPipelineState = PS_RED;
         }
@@ -3407,17 +3439,18 @@ nsConnectionEntry::CreditPenalty()
         for (int32_t i = 0; i < nsAHttpTransaction::CLASS_MAX; ++i) {
             mPipeliningClassPenalty[i]  =
                 std::max(int32_t(mPipeliningClassPenalty[i] - creditsEarned), 0);
             failed = failed || (mPipeliningClassPenalty[i] > 0);
         }
 
         // update last credit mark to reflect elapsed time
         mLastCreditTime += TimeDuration::FromSeconds(creditsEarned << 4);
-    } else {
+    }
+    else {
         failed = true;                         /* just assume this */
     }
 
     // If we are no longer red then clear the credit counter - you only
     // get credits for time spent in the red state
     if (!failed)
         mLastCreditTime = TimeStamp();    /* reset to null timestamp */
 
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -260,20 +260,20 @@ private:
     // pending transactions.
     //
     class nsConnectionEntry
     {
     public:
         nsConnectionEntry(nsHttpConnectionInfo *ci);
         ~nsConnectionEntry();
 
-        nsRefPtr<nsHttpConnectionInfo> mConnInfo;
-        nsTArray<nsRefPtr<nsHttpTransaction> > mPendingQ;    // pending transaction queue
-        nsTArray<nsRefPtr<nsHttpConnection> >  mActiveConns; // active connections
-        nsTArray<nsRefPtr<nsHttpConnection> >  mIdleConns;   // idle persistent connections
+        nsHttpConnectionInfo        *mConnInfo;
+        nsTArray<nsHttpTransaction*> mPendingQ;    // pending transaction queue
+        nsTArray<nsHttpConnection*>  mActiveConns; // active connections
+        nsTArray<nsHttpConnection*>  mIdleConns;   // idle persistent connections
         nsTArray<nsHalfOpenSocket*>  mHalfOpens;   // half open connections
 
         // calculate the number of half open sockets that have not had at least 1
         // connection complete
         uint32_t UnconnectedHalfOpens();
 
         // Remove a particular half open socket from the mHalfOpens array
         void RemoveHalfOpen(nsHalfOpenSocket *);
@@ -374,28 +374,26 @@ private:
     //
     // thin wrapper around a real connection, used to keep track of references
     // to the connection to determine when the connection may be reused.  the
     // transaction (or pipeline) owns a reference to this handle.  this extra
     // layer of indirection greatly simplifies consumer code, avoiding the
     // need for consumer code to know when to give the connection back to the
     // connection manager.
     //
-    class nsConnectionHandle MOZ_FINAL : public nsAHttpConnection
+    class nsConnectionHandle : public nsAHttpConnection
     {
     public:
         NS_DECL_THREADSAFE_ISUPPORTS
         NS_DECL_NSAHTTPCONNECTION(mConn)
 
-        nsConnectionHandle(nsHttpConnection *conn) : mConn(conn) { }
+        nsConnectionHandle(nsHttpConnection *conn) { NS_ADDREF(mConn = conn); }
         virtual ~nsConnectionHandle();
-        void Reset() { mConn = nullptr; }
 
-    private:
-        nsRefPtr<nsHttpConnection> mConn;
+        nsHttpConnection *mConn;
     };
 
     // nsHalfOpenSocket is used to hold the state of an opening TCP socket
     // while we wait for it to establish and bind it to a connection
 
     class nsHalfOpenSocket MOZ_FINAL : public nsIOutputStreamCallback,
                                        public nsITransportEventSink,
                                        public nsIInterfaceRequestor,
@@ -517,18 +515,16 @@ private:
     void     ReportProxyTelemetry(nsConnectionEntry *ent);
     nsresult CreateTransport(nsConnectionEntry *, nsAHttpTransaction *,
                              uint32_t, bool);
     void     AddActiveConn(nsHttpConnection *, nsConnectionEntry *);
     void     DecrementActiveConnCount(nsHttpConnection *);
     void     StartedConnect();
     void     RecvdConnect();
 
-    static void InsertTransactionSorted(nsTArray<nsRefPtr<nsHttpTransaction> > &,
-                                        nsHttpTransaction *);
     nsConnectionEntry *GetOrCreateConnectionEntry(nsHttpConnectionInfo *);
 
     nsresult MakeNewConnection(nsConnectionEntry *ent,
                                nsHttpTransaction *trans);
     bool     AddToShortestPipeline(nsConnectionEntry *ent,
                                    nsHttpTransaction *trans,
                                    nsHttpTransaction::Classifier classification,
                                    uint16_t depthLimit);
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -106,35 +106,41 @@ namespace net {
 
 static nsresult
 NewURI(const nsACString &aSpec,
        const char *aCharset,
        nsIURI *aBaseURI,
        int32_t aDefaultPort,
        nsIURI **aURI)
 {
-    nsRefPtr<nsStandardURL> url = new nsStandardURL();
+    nsStandardURL *url = new nsStandardURL();
+    if (!url)
+        return NS_ERROR_OUT_OF_MEMORY;
+    NS_ADDREF(url);
 
     nsresult rv = url->Init(nsIStandardURL::URLTYPE_AUTHORITY,
                             aDefaultPort, aSpec, aCharset, aBaseURI);
     if (NS_FAILED(rv)) {
+        NS_RELEASE(url);
         return rv;
     }
-    url.forget(aURI);
+
+    *aURI = url; // no QI needed
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpHandler <public>
 //-----------------------------------------------------------------------------
 
 nsHttpHandler *gHttpHandler = nullptr;
 
 nsHttpHandler::nsHttpHandler()
-    : mHttpVersion(NS_HTTP_VERSION_1_1)
+    : mConnMgr(nullptr)
+    , mHttpVersion(NS_HTTP_VERSION_1_1)
     , mProxyHttpVersion(NS_HTTP_VERSION_1_1)
     , mCapabilities(NS_HTTP_ALLOW_KEEPALIVE)
     , mReferrerLevel(0xff) // by default we always send a referrer
     , mSpoofReferrerSource(false)
     , mReferrerTrimmingPolicy(0)
     , mReferrerXOriginPolicy(0)
     , mFastFallbackToIPv4(false)
     , mProxyPipelining(true)
@@ -220,17 +226,17 @@ nsHttpHandler::nsHttpHandler()
 
 nsHttpHandler::~nsHttpHandler()
 {
     LOG(("Deleting nsHttpHandler [this=%p]\n", this));
 
     // make sure the connection manager is shutdown
     if (mConnMgr) {
         mConnMgr->Shutdown();
-        mConnMgr = nullptr;
+        NS_RELEASE(mConnMgr);
     }
 
     // Note: don't call NeckoChild::DestroyNeckoChild() here, as it's too late
     // and it'll segfault.  NeckoChild will get cleaned up by process exit.
 
     nsHttp::DestroyAtomTable();
     if (mPipelineTestTimer) {
         mPipelineTestTimer->Cancel();
@@ -378,16 +384,19 @@ nsHttpHandler::MakeNewRequestTokenBucket
 
 nsresult
 nsHttpHandler::InitConnectionMgr()
 {
     nsresult rv;
 
     if (!mConnMgr) {
         mConnMgr = new nsHttpConnectionMgr();
+        if (!mConnMgr)
+            return NS_ERROR_OUT_OF_MEMORY;
+        NS_ADDREF(mConnMgr);
     }
 
     rv = mConnMgr->Init(mMaxConnections,
                         mMaxPersistentConnectionsPerServer,
                         mMaxPersistentConnectionsPerProxy,
                         mMaxRequestDelay,
                         mMaxPipelinedRequests,
                         mMaxOptimisticPipelinedRequests);
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -340,17 +340,17 @@ private:
     nsMainThreadPtrHandle<nsICookieService>          mCookieService;
     nsMainThreadPtrHandle<nsISiteSecurityService>    mSSService;
 
     // the authentication credentials cache
     nsHttpAuthCache mAuthCache;
     nsHttpAuthCache mPrivateAuthCache;
 
     // the connection manager
-    nsRefPtr<nsHttpConnectionMgr> mConnMgr;
+    nsHttpConnectionMgr *mConnMgr;
 
     //
     // prefs
     //
 
     uint8_t  mHttpVersion;
     uint8_t  mProxyHttpVersion;
     uint32_t mCapabilities;
--- a/netwerk/protocol/http/nsHttpPipeline.cpp
+++ b/netwerk/protocol/http/nsHttpPipeline.cpp
@@ -57,17 +57,18 @@ private:
     uint32_t    mBufLen;
 };
 
 //-----------------------------------------------------------------------------
 // nsHttpPipeline <public>
 //-----------------------------------------------------------------------------
 
 nsHttpPipeline::nsHttpPipeline()
-    : mStatus(NS_OK)
+    : mConnection(nullptr)
+    , mStatus(NS_OK)
     , mRequestIsPartial(false)
     , mResponseIsPartial(false)
     , mClosed(false)
     , mUtilizedPipeline(false)
     , mPushBackBuf(nullptr)
     , mPushBackLen(0)
     , mPushBackMax(0)
     , mHttp1xTransactionCount(0)
@@ -77,29 +78,31 @@ nsHttpPipeline::nsHttpPipeline()
 {
 }
 
 nsHttpPipeline::~nsHttpPipeline()
 {
     // make sure we aren't still holding onto any transactions!
     Close(NS_ERROR_ABORT);
 
+    NS_IF_RELEASE(mConnection);
+
     if (mPushBackBuf)
         free(mPushBackBuf);
 }
 
 nsresult
 nsHttpPipeline::AddTransaction(nsAHttpTransaction *trans)
 {
     LOG(("nsHttpPipeline::AddTransaction [this=%p trans=%x]\n", this, trans));
 
     if (mRequestQ.Length() || mResponseQ.Length())
         mUtilizedPipeline = true;
 
-    trans->AddRef(); // ref held by mRequestQ
+    NS_ADDREF(trans);
     mRequestQ.AppendElement(trans);
     uint32_t qlen = PipelineDepth();
 
     if (qlen != 1) {
         trans->SetPipelinePosition(qlen);
     }
     else {
         // do it for this case in case an idempotent cancellation
@@ -197,21 +200,20 @@ nsHttpPipeline::OnHeadersAvailable(nsAHt
         // The received headers have expanded the eligible
         // pipeline depth for this connection
         gHttpHandler->ConnMgr()->ProcessPendingQForEntry(ci);
 
     return rv;
 }
 
 void
-nsHttpPipeline::CloseTransaction(nsAHttpTransaction *aTrans, nsresult reason)
+nsHttpPipeline::CloseTransaction(nsAHttpTransaction *trans, nsresult reason)
 {
-    nsRefPtr<nsAHttpTransaction> trans(dont_AddRef(aTrans));
     LOG(("nsHttpPipeline::CloseTransaction [this=%p trans=%x reason=%x]\n",
-         this, trans.get(), reason));
+        this, trans, reason));
 
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     MOZ_ASSERT(NS_FAILED(reason), "expecting failure code");
 
     // the specified transaction is to be closed with the given "reason"
 
     int32_t index;
     bool killPipeline = false;
@@ -236,17 +238,17 @@ nsHttpPipeline::CloseTransaction(nsAHttp
         killPipeline = true;
     }
 
     // Marking this connection as non-reusable prevents other items from being
     // added to it and causes it to be torn down soon.
     DontReuse();
 
     trans->Close(reason);
-    trans = nullptr;
+    NS_RELEASE(trans);
 
     if (killPipeline) {
         // reschedule anything from this pipeline onto a different connection
         CancelPipeline(reason);
     }
 
     // If all the transactions have been removed then we can close the connection
     // right away.
@@ -378,21 +380,22 @@ nsHttpPipeline::TakeSubTransactions(
 {
     LOG(("nsHttpPipeline::TakeSubTransactions [this=%p]\n", this));
 
     if (mResponseQ.Length() || mRequestIsPartial)
         return NS_ERROR_ALREADY_OPENED;
 
     int32_t i, count = mRequestQ.Length();
     for (i = 0; i < count; ++i) {
-        nsRefPtr<nsAHttpTransaction> trans(dont_AddRef(Request(i)));
+        nsAHttpTransaction *trans = Request(i);
         // set the transaction conneciton object back to the underlying
         // nsHttpConnectionHandle
         trans->SetConnection(mConnection);
         outTransactions.AppendElement(trans);
+        NS_RELEASE(trans);
     }
     mRequestQ.Clear();
 
     LOG(("   took %d\n", count));
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
@@ -401,23 +404,24 @@ nsHttpPipeline::TakeSubTransactions(
 
 void
 nsHttpPipeline::SetConnection(nsAHttpConnection *conn)
 {
     LOG(("nsHttpPipeline::SetConnection [this=%p conn=%x]\n", this, conn));
 
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     MOZ_ASSERT(!mConnection, "already have a connection");
-    mConnection = conn;
+
+    NS_IF_ADDREF(mConnection = conn);
 }
 
 nsAHttpConnection *
 nsHttpPipeline::Connection()
 {
-    LOG(("nsHttpPipeline::Connection [this=%p conn=%x]\n", this, mConnection.get()));
+    LOG(("nsHttpPipeline::Connection [this=%p conn=%x]\n", this, mConnection));
 
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     return mConnection;
 }
 
 void
 nsHttpPipeline::GetSecurityCallbacks(nsIInterfaceRequestor **result)
 {
@@ -679,17 +683,17 @@ nsHttpPipeline::WriteSegments(nsAHttpSeg
         //
         rv = trans->WriteSegments(writer, count, countWritten);
 
         if (rv == NS_BASE_STREAM_CLOSED || trans->IsDone()) {
             trans->Close(NS_OK);
 
             // Release the transaction if it is not IsProxyConnectInProgress()
             if (trans == Response(0)) {
-                nsRefPtr<nsAHttpTransaction> listReference(dont_AddRef(trans));
+                NS_RELEASE(trans);
                 mResponseQ.RemoveElementAt(0);
                 mResponseIsPartial = false;
                 ++mHttp1xTransactionCount;
             }
 
             // ask the connection manager to add additional transactions
             // to our pipeline.
             nsRefPtr<nsHttpConnectionInfo> ci;
@@ -722,47 +726,49 @@ nsHttpPipeline::WriteSegments(nsAHttpSeg
 
     return rv;
 }
 
 uint32_t
 nsHttpPipeline::CancelPipeline(nsresult originalReason)
 {
     uint32_t i, reqLen, respLen, total;
+    nsAHttpTransaction *trans;
 
     reqLen = mRequestQ.Length();
     respLen = mResponseQ.Length();
     total = reqLen + respLen;
 
     // don't count the first response, if presnet
     if (respLen)
         total--;
 
     if (!total)
         return 0;
 
     // any pending requests can ignore this error and be restarted
     // unless it is during a CONNECT tunnel request
     for (i = 0; i < reqLen; ++i) {
-        // Each element on the list has a reference held by the list
-        nsRefPtr<nsAHttpTransaction> trans(dont_AddRef(Request(i)));
+        trans = Request(i);
         if (mConnection && mConnection->IsProxyConnectInProgress())
             trans->Close(originalReason);
         else
             trans->Close(NS_ERROR_NET_RESET);
+        NS_RELEASE(trans);
     }
     mRequestQ.Clear();
 
     // any pending responses can be restarted except for the first one,
     // that we might want to finish on this pipeline or cancel individually.
     // Higher levels of callers ensure that we don't process non-idempotent
     // tranasction with the NS_HTTP_ALLOW_PIPELINING bit set
     for (i = 1; i < respLen; ++i) {
-        nsRefPtr<nsAHttpTransaction> trans(dont_AddRef(Response(i)));
+        trans = Response(i);
         trans->Close(NS_ERROR_NET_RESET);
+        NS_RELEASE(trans);
     }
 
     if (respLen > 1)
         mResponseQ.TruncateLength(1);
 
     DontReuse();
     Classify(nsAHttpTransaction::CLASS_SOLO);
 
@@ -790,36 +796,35 @@ nsHttpPipeline::Close(nsresult reason)
     // numRescheduled can be 0 if there is just a single response in the
     // pipeline object. That isn't really a meaningful pipeline that
     // has been forced to be rescheduled so it does not need to generate
     // negative feedback.
     if (ci && numRescheduled)
         gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
             ci, nsHttpConnectionMgr::RedCanceledPipeline, nullptr, 0);
 
-    if (!Response(0)) {
+    nsAHttpTransaction *trans = Response(0);
+    if (!trans)
         return;
-    }
-    nsRefPtr<nsAHttpTransaction> trans(dont_AddRef(Response(0)));
 
     // The current transaction can be restarted via reset
     // if the response has not started to arrive and the reason
     // for failure is innocuous (e.g. not an SSL error)
     if (!mResponseIsPartial &&
         (reason == NS_ERROR_NET_RESET ||
          reason == NS_OK ||
          reason == NS_ERROR_NET_TIMEOUT ||
          reason == NS_BASE_STREAM_CLOSED)) {
         trans->Close(NS_ERROR_NET_RESET);
     }
     else {
         trans->Close(reason);
     }
 
-    trans = nullptr;
+    NS_RELEASE(trans);
     mResponseQ.Clear();
 }
 
 nsresult
 nsHttpPipeline::OnReadSegment(const char *segment,
                               uint32_t count,
                               uint32_t *countRead)
 {
--- a/netwerk/protocol/http/nsHttpPipeline.h
+++ b/netwerk/protocol/http/nsHttpPipeline.h
@@ -53,17 +53,17 @@ private:
             return nullptr;
 
         return mResponseQ[i];
     }
 
     // overload of nsAHttpTransaction::QueryPipeline()
     nsHttpPipeline *QueryPipeline();
 
-    nsRefPtr<nsAHttpConnection>   mConnection;
+    nsAHttpConnection            *mConnection;
     nsTArray<nsAHttpTransaction*> mRequestQ;  // array of transactions
     nsTArray<nsAHttpTransaction*> mResponseQ; // array of transactions
     nsresult                      mStatus;
 
     // these flags indicate whether or not the first request or response
     // is partial.  a partial request means that Request(0) has been
     // partially written out to the socket.  a partial response means
     // that Response(0) has been partially read in from the socket.
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -84,16 +84,18 @@ LogHeaders(const char *lineStart)
 
 //-----------------------------------------------------------------------------
 // nsHttpTransaction <public>
 //-----------------------------------------------------------------------------
 
 nsHttpTransaction::nsHttpTransaction()
     : mCallbacksLock("transaction mCallbacks lock")
     , mRequestSize(0)
+    , mConnection(nullptr)
+    , mConnInfo(nullptr)
     , mRequestHead(nullptr)
     , mResponseHead(nullptr)
     , mContentLength(-1)
     , mContentRead(0)
     , mInvalidResponseBytesRead(0)
     , mChunkedDecoder(nullptr)
     , mStatus(NS_OK)
     , mPriority(0)
@@ -142,16 +144,19 @@ nsHttpTransaction::~nsHttpTransaction()
     if (mTokenBucketCancel) {
         mTokenBucketCancel->Cancel(NS_ERROR_ABORT);
         mTokenBucketCancel = nullptr;
     }
 
     // Force the callbacks to be released right now
     mCallbacks = nullptr;
 
+    NS_IF_RELEASE(mConnection);
+    NS_IF_RELEASE(mConnInfo);
+
     delete mResponseHead;
     delete mForTakeResponseHead;
     delete mChunkedDecoder;
     ReleaseBlockingTransaction();
 }
 
 nsHttpTransaction::Classifier
 nsHttpTransaction::Classify()
@@ -259,17 +264,17 @@ nsHttpTransaction::Init(uint32_t caps,
     // if the activity observer is not active. when the observer is active
     // we need not to coalesce any events to get all expected notifications
     // of the transaction state, necessary for correct debugging and logging.
     rv = net_NewTransportEventSinkProxy(getter_AddRefs(mTransportSink),
                                         eventsink, target,
                                         !activityDistributorActive);
     if (NS_FAILED(rv)) return rv;
 
-    mConnInfo = cinfo;
+    NS_ADDREF(mConnInfo = cinfo);
     mCallbacks = callbacks;
     mConsumerTarget = target;
     mCaps = caps;
 
     if (requestHead->Method() == nsHttp::Head)
         mNoContent = true;
 
     // Make sure that there is "Content-Length: 0" header in the requestHead
@@ -435,17 +440,18 @@ nsHttpTransaction::TakeSubTransactions(
 
 //----------------------------------------------------------------------------
 // nsHttpTransaction::nsAHttpTransaction
 //----------------------------------------------------------------------------
 
 void
 nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
 {
-    mConnection = conn;
+    NS_IF_RELEASE(mConnection);
+    NS_IF_ADDREF(mConnection = conn);
 
     if (conn) {
         MOZ_EVENT_TRACER_EXEC(static_cast<nsAHttpTransaction*>(this),
                               "net::http::transaction");
     }
 }
 
 void
@@ -950,19 +956,18 @@ nsHttpTransaction::Close(nsresult reason
 
     // mTimings.responseEnd is normally recorded based on the end of a
     // HTTP delimiter such as chunked-encodings or content-length. However,
     // EOF or an error still require an end time be recorded.
     if (TimingEnabled() &&
         mTimings.responseEnd.IsNull() && !mTimings.responseStart.IsNull())
         mTimings.responseEnd = TimeStamp::Now();
 
-    if (relConn) {
-        mConnection = nullptr;
-    }
+    if (relConn && mConnection)
+        NS_RELEASE(mConnection);
 
     // save network statistics in the end of transaction
     SaveNetworkStats(true);
 
     mStatus = reason;
     mTransactionDone = true; // forcibly flag the transaction as complete
     mClosed = true;
     ReleaseBlockingTransaction();
@@ -1106,17 +1111,17 @@ nsHttpTransaction::Restart()
 
     // rewind streams in case we already wrote out the request
     nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mRequestStream);
     if (seekable)
         seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
 
     // clear old connection state...
     mSecurityInfo = 0;
-    mConnection = nullptr;
+    NS_IF_RELEASE(mConnection);
 
     // disable pipelining for the next attempt in case pipelining caused the
     // reset.  this is being overly cautious since we don't know if pipelining
     // was the problem here.
     mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
     SetPipelinePosition(0);
 
     return gHttpHandler->InitiateTransaction(this, mPriority);
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -180,21 +180,20 @@ private:
 
     nsCOMPtr<nsISupports>             mChannel;
     nsCOMPtr<nsIHttpActivityObserver> mActivityDistributor;
 
     nsCString                       mReqHeaderBuf;    // flattened request headers
     nsCOMPtr<nsIInputStream>        mRequestStream;
     uint64_t                        mRequestSize;
 
-    nsRefPtr<nsHttpConnectionInfo>  mConnInfo;
-    nsRefPtr<nsAHttpConnection>     mConnection;
-
+    nsAHttpConnection              *mConnection;      // hard ref
+    nsHttpConnectionInfo           *mConnInfo;        // hard ref
     nsHttpRequestHead              *mRequestHead;     // weak ref
-    nsHttpResponseHead             *mResponseHead;    // owning ref
+    nsHttpResponseHead             *mResponseHead;    // hard ref
 
     nsAHttpSegmentReader           *mReader;
     nsAHttpSegmentWriter           *mWriter;
 
     nsCString                       mLineBuf;         // may contain a partial line
 
     int64_t                         mContentLength;   // equals -1 if unknown
     int64_t                         mContentRead;     // count of consumed content bytes