зеркало из https://github.com/mozilla/gecko-dev.git
bug 970279 - tie null transactions to cancel and timeout events r=hurley
This commit is contained in:
Родитель
1b79885a12
Коммит
c3a11f47df
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче