bug 970279 - tie null transactions to cancel and timeout events r=hurley

This commit is contained in:
Patrick McManus 2014-02-07 17:30:36 -05:00
Родитель 1b79885a12
Коммит c3a11f47df
6 изменённых файлов: 68 добавлений и 18 удалений

Просмотреть файл

@ -34,8 +34,13 @@ public:
nsHttpConnectionInfo *ConnectionInfo() { return mConnectionInfo; }
// An overload of nsAHttpTransaction::IsNullTransaction()
bool IsNullTransaction() { return true; }
// Overload of nsAHttpTransaction methods
bool IsNullTransaction() MOZ_OVERRIDE MOZ_FINAL { return true; }
bool ResponseTimeoutEnabled() const MOZ_OVERRIDE MOZ_FINAL {return true; }
PRIntervalTime ResponseTimeout() MOZ_OVERRIDE MOZ_FINAL
{
return PR_SecondsToInterval(15);
}
private:

Просмотреть файл

@ -127,7 +127,9 @@ public:
// return the load group connection information associated with the transaction
virtual nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() { return nullptr; }
virtual bool ResponseTimeoutEnabled() const { return false; }
// The base definition of these is done in nsHttpTransaction.cpp
virtual bool ResponseTimeoutEnabled() const;
virtual PRIntervalTime ResponseTimeout();
// Every transaction is classified into one of the types below. When using
// HTTP pipelines, only transactions with the same type appear on the same

Просмотреть файл

@ -361,7 +361,7 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
// The overflow state is not needed between activations
mInputOverflow = nullptr;
mResponseTimeoutEnabled = mHttpHandler->ResponseTimeout() > 0 &&
mResponseTimeoutEnabled = mTransaction->ResponseTimeout() > 0 &&
mTransaction->ResponseTimeoutEnabled();
rv = OnOutputStreamReady(mSocketOut);
@ -1002,14 +1002,14 @@ nsHttpConnection::ReadTimeoutTick(PRIntervalTime now)
}
uint32_t nextTickAfter = UINT32_MAX;
// Timeout if the response is taking too long to arrive.
if (mResponseTimeoutEnabled) {
PRIntervalTime initialResponseDelta = now - mLastWriteTime;
if (initialResponseDelta > gHttpHandler->ResponseTimeout()) {
if (initialResponseDelta > mTransaction->ResponseTimeout()) {
LOG(("canceling transaction: no response for %ums: timeout is %dms\n",
PR_IntervalToMilliseconds(initialResponseDelta),
PR_IntervalToMilliseconds(gHttpHandler->ResponseTimeout())));
PR_IntervalToMilliseconds(mTransaction->ResponseTimeout())));
mResponseTimeoutEnabled = false;
@ -1017,8 +1017,8 @@ nsHttpConnection::ReadTimeoutTick(PRIntervalTime now)
CloseTransaction(mTransaction, NS_ERROR_NET_TIMEOUT);
return UINT32_MAX;
}
nextTickAfter = PR_IntervalToSeconds(gHttpHandler->ResponseTimeout()) -
PR_IntervalToSeconds(initialResponseDelta);
nextTickAfter = PR_IntervalToSeconds(mTransaction->ResponseTimeout()) -
PR_IntervalToSeconds(initialResponseDelta);
nextTickAfter = std::max(nextTickAfter, 1U);
}

Просмотреть файл

@ -1368,6 +1368,9 @@ nsHttpConnectionMgr::MakeNewConnection(nsConnectionEntry *ent,
if (!(trans->Caps() & NS_HTTP_DISALLOW_SPDY) &&
(trans->Caps() & NS_HTTP_ALLOW_KEEPALIVE) &&
RestrictConnections(ent)) {
LOG(("nsHttpConnectionMgr::MakeNewConnection [ci = %s] "
"Not Available Due to RestrictConnections()\n",
ent->mConnInfo->HashKey().get()));
return NS_ERROR_NOT_AVAILABLE;
}
@ -1933,6 +1936,8 @@ nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
MOZ_ASSERT(trans->Caps() & NS_HTTP_STICKY_CONNECTION);
MOZ_ASSERT(((int32_t)ent->mActiveConns.IndexOf(conn)) != -1,
"Sticky Connection Not In Active List");
LOG(("nsHttpConnectionMgr::ProcessNewTransaction trans=%p "
"sticky connection=%p\n", trans, conn.get()));
trans->SetConnection(nullptr);
rv = DispatchTransaction(ent, trans, conn);
}
@ -2195,21 +2200,40 @@ nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, void *param)
// transaction directly (removing it from the pending queue first).
//
nsAHttpConnection *conn = trans->Connection();
if (conn && !trans->IsDone())
if (conn && !trans->IsDone()) {
conn->CloseTransaction(trans, closeCode);
else {
nsConnectionEntry *ent = LookupConnectionEntry(trans->ConnectionInfo(),
nullptr, trans);
} 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));
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
// to assume that's what was meant by the cancel we did receive if
// it only applied to something in the queue.
for (uint32_t index = 0; 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, liveTransaction, activeConn));
activeConn->CloseTransaction(liveTransaction, closeCode);
}
}
}
NS_RELEASE(trans);
}
@ -2494,8 +2518,11 @@ nsHttpConnectionMgr::TimeoutTickCB(const nsACString &key,
{
nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
LOG(("nsHttpConnectionMgr::TimeoutTickCB() this=%p host=%s\n",
self, ent->mConnInfo->Host()));
LOG(("nsHttpConnectionMgr::TimeoutTickCB() this=%p host=%s "
"idle=%d active=%d half-len=%d pending=%d\n",
self, ent->mConnInfo->Host(), ent->mIdleConns.Length(),
ent->mActiveConns.Length(), ent->mHalfOpens.Length(),
ent->mPendingQ.Length()));
// first call the tick handler for each active connection
PRIntervalTime now = PR_IntervalNow();

Просмотреть файл

@ -1035,6 +1035,24 @@ nsHttpTransaction::PipelinePosition()
return mPipelinePosition;
}
bool // NOTE BASE CLASS
nsAHttpTransaction::ResponseTimeoutEnabled() const
{
return false;
}
PRIntervalTime // NOTE BASE CLASS
nsAHttpTransaction::ResponseTimeout()
{
return gHttpHandler->ResponseTimeout();
}
bool
nsHttpTransaction::ResponseTimeoutEnabled() const
{
return mResponseTimeoutEnabled;
}
//-----------------------------------------------------------------------------
// nsHttpTransaction <private>
//-----------------------------------------------------------------------------

Просмотреть файл

@ -147,9 +147,7 @@ private:
bool TimingEnabled() const { return mCaps & NS_HTTP_TIMING_ENABLED; }
bool ResponseTimeoutEnabled() const MOZ_OVERRIDE MOZ_FINAL {
return mResponseTimeoutEnabled;
}
bool ResponseTimeoutEnabled() const MOZ_FINAL;
private:
class UpdateSecurityCallbacks : public nsRunnable