Backed out changeset d11fb28f9b9c (bug 1344171) for crashes in test_altsvc.js

This commit is contained in:
Phil Ringnalda 2017-03-28 21:04:43 -07:00
Родитель 51f4fcc4e2
Коммит 93abf48bf7
2 изменённых файлов: 63 добавлений и 153 удалений

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

@ -677,29 +677,6 @@ nsHttpConnectionMgr::CloseIdleConnection(nsHttpConnection *conn)
return NS_OK;
}
nsresult
nsHttpConnectionMgr::RemoveIdleConnection(nsHttpConnection *conn)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
LOG(("nsHttpConnectionMgr::RemoveIdleConnection %p conn=%p",
this, 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;
}
mNumIdleConns--;
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
@ -943,10 +920,14 @@ nsHttpConnectionMgr::DispatchPendingQ(nsTArray<RefPtr<nsHttpConnectionMgr::Pendi
MOZ_ASSERT(!pendingTransInfo->mActiveConn);
RefPtr<nsHalfOpenSocket> halfOpen =
do_QueryReferent(pendingTransInfo->mHalfOpen);
LOG(("nsHttpConnectionMgr::ProcessPendingQForEntry "
"[trans=%p, halfOpen=%p]\n",
pendingTransInfo->mTransaction.get(), halfOpen.get()));
if (halfOpen) {
// The half open socket was made for this transaction, in
// that case ent->mHalfOpens[j]->Transaction() == trans or
// the half open socket was opened speculatively and this
// transaction took it (in this case it must be:
// ent->mHalfOpens[j]->Transaction().IsNullTransaction())
MOZ_ASSERT(halfOpen->Transaction()->IsNullTransaction() ||
halfOpen->Transaction() == pendingTransInfo->mTransaction);
alreadyHalfOpenOrWaitingForTLS = true;
} else {
// If we have not found the halfOpen socket, remove the pointer.
@ -956,9 +937,6 @@ nsHttpConnectionMgr::DispatchPendingQ(nsTArray<RefPtr<nsHttpConnectionMgr::Pendi
MOZ_ASSERT(!pendingTransInfo->mHalfOpen);
RefPtr<nsHttpConnection> activeConn =
do_QueryReferent(pendingTransInfo->mActiveConn);
LOG(("nsHttpConnectionMgr::ProcessPendingQForEntry "
"[trans=%p, activeConn=%p]\n",
pendingTransInfo->mTransaction.get(), activeConn.get()));
// Check if this transaction claimed a connection that is still
// performing tls handshake with a NullHttpTransaction or it is between
// finishing tls and reclaiming (When nullTrans finishes tls handshake,
@ -1288,17 +1266,34 @@ nsHttpConnectionMgr::MakeNewConnection(nsConnectionEntry *ent,
uint32_t halfOpenLength = ent->mHalfOpens.Length();
for (uint32_t i = 0; i < halfOpenLength; i++) {
if (ent->mHalfOpens[i]->Claim()) {
// We've found a speculative connection or a connection that
// is free to be used in the half open list.
// A free to be used connection is a connection that was
// open for a concrete transaction, but that trunsaction
// ended up using another connection.
if (ent->mHalfOpens[i]->IsSpeculative()) {
// We've found a speculative connection in the half
// open list. Remove the speculative bit from it and that
// connection can later be used for this transaction
// (or another one in the pending queue) - we don't
// need to open a new connection here.
LOG(("nsHttpConnectionMgr::MakeNewConnection [ci = %s]\n"
"Found a speculative or a free-to-use half open connection\n",
"Found a speculative half open connection\n",
ent->mConnInfo->HashKey().get()));
uint32_t flags;
ent->mHalfOpens[i]->SetSpeculative(false);
pendingTransInfo->mHalfOpen =
do_GetWeakReference(static_cast<nsISupportsWeakReference*>(ent->mHalfOpens[i]));
nsISocketTransport *transport = ent->mHalfOpens[i]->SocketTransport();
if (transport && NS_SUCCEEDED(transport->GetConnectionFlags(&flags))) {
flags &= ~nsISocketTransport::DISABLE_RFC1918;
transport->SetConnectionFlags(flags);
}
Telemetry::AutoCounter<Telemetry::HTTPCONNMGR_USED_SPECULATIVE_CONN> usedSpeculativeConn;
++usedSpeculativeConn;
if (ent->mHalfOpens[i]->IsFromPredictor()) {
Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRECONNECTS_USED> totalPreconnectsUsed;
++totalPreconnectsUsed;
}
// return OK because we have essentially opened a new connection
// by converting a speculative half-open to general use
return NS_OK;
@ -1892,12 +1887,13 @@ nsHttpConnectionMgr::ReleaseClaimedSockets(nsConnectionEntry *ent,
if (pendingTransInfo->mHalfOpen) {
RefPtr<nsHalfOpenSocket> halfOpen =
do_QueryReferent(pendingTransInfo->mHalfOpen);
LOG(("nsHttpConnectionMgr::ReleaseClaimedSockets "
"[trans=%p halfOpen=%p]",
pendingTransInfo->mTransaction.get(),
halfOpen.get()));
if (halfOpen) {
halfOpen->Unclaim();
if (halfOpen->Transaction() &&
halfOpen->Transaction()->IsNullTransaction()) {
LOG(("nsHttpConnectionMgr::ReleaseClaimedSockets - mark halfOpne %p "
"speculative again.", halfOpen.get()));
halfOpen->SetSpeculative(true);
}
}
pendingTransInfo->mHalfOpen = nullptr;
} else if (pendingTransInfo->mActiveConn) {
@ -1923,16 +1919,21 @@ nsHttpConnectionMgr::CreateTransport(nsConnectionEntry *ent,
PendingTransactionInfo *pendingTransInfo)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
MOZ_ASSERT((speculative && !pendingTransInfo) ||
(!speculative && pendingTransInfo));
RefPtr<nsHalfOpenSocket> sock = new nsHalfOpenSocket(ent, trans, caps,
speculative,
isFromPredictor);
RefPtr<nsHalfOpenSocket> sock = new nsHalfOpenSocket(ent, trans, caps);
if (speculative) {
sock->SetSpeculative(true);
sock->SetAllow1918(allow1918);
Telemetry::AutoCounter<Telemetry::HTTPCONNMGR_TOTAL_SPECULATIVE_CONN> totalSpeculativeConn;
++totalSpeculativeConn;
if (isFromPredictor) {
sock->SetIsFromPredictor(true);
Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRECONNECTS_CREATED> totalPreconnectsCreated;
++totalPreconnectsCreated;
}
}
// The socket stream holds the reference to the half open
// socket - so if the stream fails to init the half open
// will go away.
@ -1942,8 +1943,6 @@ nsHttpConnectionMgr::CreateTransport(nsConnectionEntry *ent,
if (pendingTransInfo) {
pendingTransInfo->mHalfOpen =
do_GetWeakReference(static_cast<nsISupportsWeakReference*>(sock));
DebugOnly<bool> claimed = sock->Claim();
MOZ_ASSERT(claimed);
}
ent->mHalfOpens.AppendElement(sock);
@ -2292,6 +2291,8 @@ nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, ARefBase *param)
RefPtr<nsHalfOpenSocket> half =
do_QueryReferent(pendingTransInfo->mHalfOpen);
if (half) {
MOZ_ASSERT(trans == half->Transaction() ||
half->Transaction()->IsNullTransaction());
half->Abandon();
}
pendingTransInfo->mHalfOpen = nullptr;
@ -3050,35 +3051,21 @@ NS_INTERFACE_MAP_END
nsHttpConnectionMgr::
nsHalfOpenSocket::nsHalfOpenSocket(nsConnectionEntry *ent,
nsAHttpTransaction *trans,
uint32_t caps,
bool speculative,
bool isFromPredictor)
uint32_t caps)
: mEnt(ent)
, mTransaction(trans)
, mDispatchedMTransaction(false)
, mCaps(caps)
, mSpeculative(speculative)
, mIsFromPredictor(isFromPredictor)
, mSpeculative(false)
, mIsFromPredictor(false)
, mAllow1918(true)
, mHasConnected(false)
, mPrimaryConnectedOK(false)
, mBackupConnectedOK(false)
, mFreeToUse(true)
, mPrimaryStreamStatus(NS_OK)
{
MOZ_ASSERT(ent && trans, "constructor with null arguments");
LOG(("Creating nsHalfOpenSocket [this=%p trans=%p ent=%s key=%s]\n",
this, trans, ent->mConnInfo->Origin(), ent->mConnInfo->HashKey().get()));
if (speculative) {
Telemetry::AutoCounter<Telemetry::HTTPCONNMGR_TOTAL_SPECULATIVE_CONN> totalSpeculativeConn;
++totalSpeculativeConn;
if (isFromPredictor) {
Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRECONNECTS_CREATED> totalPreconnectsCreated;
++totalPreconnectsCreated;
}
}
}
nsHttpConnectionMgr::nsHalfOpenSocket::~nsHalfOpenSocket()
@ -3255,6 +3242,8 @@ nsresult
nsHttpConnectionMgr::nsHalfOpenSocket::SetupBackupStreams()
{
MOZ_ASSERT(mTransaction);
MOZ_ASSERT(!mTransaction->IsNullTransaction(),
"null transactions dont have backup streams");
mBackupSynStarted = TimeStamp::Now();
nsresult rv = SetupStreams(getter_AddRefs(mBackupTransport),
@ -3278,7 +3267,7 @@ nsHttpConnectionMgr::nsHalfOpenSocket::SetupBackupTimer()
{
uint16_t timeout = gHttpHandler->GetIdleSynTimeout();
MOZ_ASSERT(!mSynTimer, "timer already initd");
if (timeout && !mSpeculative) {
if (timeout && !mTransaction->IsDone() && !mTransaction->IsNullTransaction()) {
// Setup the timer that will establish a backup socket
// if we do not get a writable event on the main one.
// We do this because a lost SYN takes a very long time
@ -3373,6 +3362,8 @@ nsHttpConnectionMgr::nsHalfOpenSocket::Notify(nsITimer *timer)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
MOZ_ASSERT(timer == mSynTimer, "wrong timer");
MOZ_ASSERT(mTransaction && !mTransaction->IsNullTransaction(),
"null transactions dont have backup streams");
DebugOnly<nsresult> rv = SetupBackupStreams();
MOZ_ASSERT(NS_SUCCEEDED(rv));
@ -3455,6 +3446,8 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out)
mStreamIn = nullptr;
mSocketTransport = nullptr;
} else if (out == mBackupStreamOut) {
MOZ_ASSERT(!mTransaction->IsNullTransaction(),
"null transactions dont have backup streams");
TimeDuration rtt = TimeStamp::Now() - mBackupSynStarted;
rv = conn->Init(mEnt->mConnInfo,
gHttpHandler->ConnMgr()->mMaxRequestDelay,
@ -3535,35 +3528,6 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out)
LOG(("nsHalfOpenSocket::OnOutputStreamReady no transaction match "
"returning conn %p to pool\n", conn.get()));
gHttpHandler->ConnMgr()->OnMsgReclaimConnection(0, conn);
// We expect that there is at least one tranasction in the pending
// queue that can take this connection, but it can happened that
// all transactions are blocked or they have took other idle
// connections. In that case the connection has been added to the
// idle queue.
// If the connection is in the idle queue but it is using ssl, make
// a nulltransaction for it to finish ssl handshake!
int32_t idx = mEnt->mIdleConns.IndexOf(conn);
if (idx != -1) {
if (mEnt->mConnInfo->FirstHopSSL() &&
!mEnt->mConnInfo->UsingConnect()) {
DebugOnly<nsresult> rv = gHttpHandler->ConnMgr()->RemoveIdleConnection(conn);
MOZ_ASSERT(NS_SUCCEEDED(rv));
conn->EndIdleMonitoring();
RefPtr<nsAHttpTransaction> trans;
if (mTransaction->IsNullTransaction() &&
!mDispatchedMTransaction) {
mDispatchedMTransaction = true;
trans = mTransaction;
} else {
trans = new NullHttpTransaction(mEnt->mConnInfo,
callbacks, mCaps);
}
gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt);
rv = gHttpHandler->ConnMgr()->
DispatchAbstractTransaction(mEnt, trans, mCaps, conn, 0);
}
}
}
}
@ -3610,8 +3574,6 @@ nsHttpConnectionMgr::nsHalfOpenSocket::OnTransportStatus(nsITransport *trans,
return NS_OK;
}
mPrimaryStreamStatus = status;
// if we are doing spdy coalescing and haven't recorded the ip address
// for this entry before then make the hash key if our dns lookup
// just completed. We can't do coalescing if using a proxy because the
@ -3697,47 +3659,6 @@ nsHttpConnectionMgr::nsHalfOpenSocket::GetInterface(const nsIID &iid,
return NS_ERROR_NO_INTERFACE;
}
bool
nsHttpConnectionMgr::nsHalfOpenSocket::Claim()
{
if (mSpeculative) {
mSpeculative = false;
uint32_t flags;
if (mSocketTransport && NS_SUCCEEDED(mSocketTransport->GetConnectionFlags(&flags))) {
flags &= ~nsISocketTransport::DISABLE_RFC1918;
mSocketTransport->SetConnectionFlags(flags);
}
Telemetry::AutoCounter<Telemetry::HTTPCONNMGR_USED_SPECULATIVE_CONN> usedSpeculativeConn;
++usedSpeculativeConn;
if (mIsFromPredictor) {
Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRECONNECTS_USED> totalPreconnectsUsed;
++totalPreconnectsUsed;
}
if ((mPrimaryStreamStatus == NS_NET_STATUS_CONNECTING_TO) &&
mEnt && !mBackupTransport && !mSynTimer) {
SetupBackupTimer();
}
}
if (mFreeToUse) {
mFreeToUse = false;
return true;
}
return false;
}
void
nsHttpConnectionMgr::nsHalfOpenSocket::Unclaim()
{
MOZ_ASSERT(!mSpeculative && !mFreeToUse);
// We will keep the backup-timer running. Most probably this halfOpen will
// be used by a transaction from which this transaction took the halfOpen.
// (this is happening because of the transaction priority.)
mFreeToUse = true;
}
already_AddRefed<nsHttpConnection>
ConnectionHandle::TakeHttpConnection()

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

@ -184,7 +184,6 @@ public:
// the idle connection list. It is called when the idle connection detects
// that the network peer has closed the transport.
MOZ_MUST_USE nsresult CloseIdleConnection(nsHttpConnection *);
MOZ_MUST_USE nsresult RemoveIdleConnection(nsHttpConnection *);
// The connection manager needs to know when a normal HTTP connection has been
// upgraded to SPDY because the dispatch and idle semantics are a little
@ -331,9 +330,7 @@ private:
nsHalfOpenSocket(nsConnectionEntry *ent,
nsAHttpTransaction *trans,
uint32_t caps,
bool speculative,
bool isFromPredictor);
uint32_t caps);
MOZ_MUST_USE nsresult SetupStreams(nsISocketTransport **,
nsIAsyncInputStream **,
@ -351,8 +348,10 @@ private:
nsAHttpTransaction *Transaction() { return mTransaction; }
bool IsSpeculative() { return mSpeculative; }
void SetSpeculative(bool val) { mSpeculative = val; }
bool IsFromPredictor() { return mIsFromPredictor; }
void SetIsFromPredictor(bool val) { mIsFromPredictor = val; }
bool Allow1918() { return mAllow1918; }
void SetAllow1918(bool val) { mAllow1918 = val; }
@ -360,9 +359,6 @@ private:
bool HasConnected() { return mHasConnected; }
void PrintDiagnostics(nsCString &log);
bool Claim();
void Unclaim();
private:
// To find out whether |mTransaction| is still in the connection entry's
// pending queue. If the transaction is found and |removeWhenFound| is
@ -409,13 +405,6 @@ private:
bool mPrimaryConnectedOK;
bool mBackupConnectedOK;
// A nsHalfOpenSocket can be made for a concrete non-null transaction,
// but the transaction can be dispatch to another connection. In that
// case we can free this transaction to be claimed by other
// transactions.
bool mFreeToUse;
nsresult mPrimaryStreamStatus;
};
friend class nsHalfOpenSocket;