Bug 865314 - allow 6 parallel connects to new https origin r=hurley

--HG--
extra : rebase_source : 076b5ad9ec376185320eef2296cb888815297958
This commit is contained in:
Patrick McManus 2016-03-31 16:51:03 -04:00
Родитель a740b186b0
Коммит c6c1bde8c5
7 изменённых файлов: 70 добавлений и 72 удалений

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

@ -507,13 +507,6 @@ Predictor::GetIgnoreIdle(bool *ignoreIdle)
return NS_OK;
}
NS_IMETHODIMP
Predictor::GetIgnorePossibleSpdyConnections(bool *ignorePossibleSpdyConnections)
{
*ignorePossibleSpdyConnections = true;
return NS_OK;
}
NS_IMETHODIMP
Predictor::GetParallelSpeculativeConnectLimit(
uint32_t *parallelSpeculativeConnectLimit)

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

@ -37,7 +37,7 @@ interface nsISpeculativeConnect : nsISupports
* inline) to determine whether or not to actually make a speculative
* connection.
*/
[builtinclass, uuid(f6a0d1e5-369f-4abc-81ae-d370d36e4006)]
[builtinclass, uuid(1040ebe3-6ed1-45a6-8587-995e082518d7)]
interface nsISpeculativeConnectionOverrider : nsISupports
{
/**
@ -46,13 +46,6 @@ interface nsISpeculativeConnectionOverrider : nsISupports
*/
[infallible] readonly attribute unsigned long parallelSpeculativeConnectLimit;
/**
* Used to loosen the restrictions nsHttpConnectionMgr::RestrictConnections
* to allow more speculative connections when we're unsure if a host will
* connect via SPDY or not.
*/
[infallible] readonly attribute boolean ignorePossibleSpdyConnections;
/**
* Used to determine if we will ignore the existence of any currently idle
* connections when we decide whether or not to make a speculative

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

@ -550,13 +550,6 @@ AltSvcOverride::GetIgnoreIdle(bool *ignoreIdle)
return NS_OK;
}
NS_IMETHODIMP
AltSvcOverride::GetIgnorePossibleSpdyConnections(bool *ignorePossibleSpdyConnections)
{
*ignorePossibleSpdyConnections = true;
return NS_OK;
}
NS_IMETHODIMP
AltSvcOverride::GetParallelSpeculativeConnectLimit(
uint32_t *parallelSpeculativeConnectLimit)

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

@ -61,8 +61,8 @@ nsHttpConnectionMgr::OnMsgPrintDiagnostics(int32_t, ARefBase *)
ent->mHalfOpens.Length());
mLogData.AppendPrintf(" Coalescing Keys Length = %u\n",
ent->mCoalescingKeys.Length());
mLogData.AppendPrintf(" Spdy using = %d, tested = %d, preferred = %d\n",
ent->mUsingSpdy, ent->mTestedSpdy, ent->mInPreferredHash);
mLogData.AppendPrintf(" Spdy using = %d, preferred = %d\n",
ent->mUsingSpdy, ent->mInPreferredHash);
mLogData.AppendPrintf(" pipelinestate = %d penalty = %d\n",
ent->mPipelineState, ent->mPipeliningPenalty);

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

@ -159,6 +159,7 @@ nsHttpConnection::StartSpdy(uint8_t spdyVersion)
mUsingSpdyVersion = spdyVersion;
mEverUsedSpdy = true;
mSpdySession = ASpdySession::NewSpdySession(spdyVersion, mSocketTransport);
if (!mReportedSpdy) {
mReportedSpdy = true;
@ -209,7 +210,6 @@ nsHttpConnection::StartSpdy(uint8_t spdyVersion)
mProxyConnectInProgress = false;
}
mSpdySession = ASpdySession::NewSpdySession(spdyVersion, mSocketTransport);
bool spdyProxy = mConnInfo->UsingHttpsProxy() && !mTLSFilter;
if (spdyProxy) {
RefPtr<nsHttpConnectionInfo> wildCardProxyCi;

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

@ -392,7 +392,6 @@ public: // intentional!
bool mOverridesOK;
uint32_t mParallelSpeculativeConnectLimit;
bool mIgnoreIdle;
bool mIgnorePossibleSpdyConnections;
bool mIsFromPredictor;
bool mAllow1918;
@ -444,8 +443,6 @@ nsHttpConnectionMgr::SpeculativeConnect(nsHttpConnectionInfo *ci,
overrider->GetParallelSpeculativeConnectLimit(
&args->mParallelSpeculativeConnectLimit);
overrider->GetIgnoreIdle(&args->mIgnoreIdle);
overrider->GetIgnorePossibleSpdyConnections(
&args->mIgnorePossibleSpdyConnections);
overrider->GetIsFromPredictor(&args->mIsFromPredictor);
overrider->GetAllow1918(&args->mAllow1918);
}
@ -680,8 +677,6 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
if (!ent)
return;
ent->mTestedSpdy = true;
if (!usingSpdy)
return;
@ -701,13 +696,14 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
nsConnectionEntry *joinedConnection;
nsConnectionEntry *preferred = LookupPreferredHash(ent);
LOG(("ReportSpdyConnection %p,%s prefers %p,%s\n",
ent, ent->mConnInfo->Origin(), preferred,
LOG(("ReportSpdyConnection %p,%s conn %p prefers %p,%s\n",
ent, ent->mConnInfo->Origin(), conn, preferred,
preferred ? preferred->mConnInfo->Origin() : ""));
if (!preferred) {
// this becomes the preferred entry
StorePreferredHash(ent);
preferred = ent;
} else if ((preferred != ent) &&
(joinedConnection = GetSpdyPreferredEnt(ent)) &&
(joinedConnection != ent)) {
@ -718,8 +714,7 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
// new transactions migrate over.
LOG(("ReportSpdyConnection graceful close of conn=%p ent=%p to "
"migrate to preferred\n", conn, ent));
"migrate to preferred (desharding)\n", conn, ent));
conn->DontReuse();
} else if (preferred != ent) {
LOG (("ReportSpdyConnection preferred host may be in false start or "
@ -727,6 +722,36 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
"abandon this connection yet."));
}
if ((preferred == ent) && conn->CanDirectlyActivate()) {
// this is a new spdy connection to the preferred entry
// Cancel any other pending connections - their associated transactions
// are in the pending queue and will be dispatched onto this connection
for (int32_t index = ent->mHalfOpens.Length() - 1;
index >= 0; --index) {
LOG(("ReportSpdyConnection forcing halfopen abandon %p\n",
ent->mHalfOpens[index]));
ent->mHalfOpens[index]->Abandon();
}
if (ent->mActiveConns.Length() > 1) {
// this is a new connection to an established preferred spdy host.
// if there is more than 1 live and established spdy connection (e.g.
// some could still be handshaking, shutting down, etc..) then close
// this one down after any transactions that are on it are complete.
// This probably happened due to the parallel connection algorithm
// that is used only before the host is known to speak spdy.
for (uint32_t index = 0; index < ent->mActiveConns.Length(); ++index) {
nsHttpConnection *otherConn = ent->mActiveConns[index];
if (otherConn != conn) {
LOG(("ReportSpdyConnection shutting down connection (%p) because new "
"spdy connection (%p) takes precedence\n", otherConn, conn));
otherConn->DontReuse();
}
}
}
}
ProcessPendingQ(ent->mConnInfo);
PostEvent(&nsHttpConnectionMgr::OnMsgProcessAllSpdyPendingQ);
}
@ -1085,8 +1110,7 @@ nsHttpConnectionMgr::ClosePersistentConnections(nsConnectionEntry *ent)
}
bool
nsHttpConnectionMgr::RestrictConnections(nsConnectionEntry *ent,
bool ignorePossibleSpdyConnections)
nsHttpConnectionMgr::RestrictConnections(nsConnectionEntry *ent)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
@ -1094,11 +1118,9 @@ nsHttpConnectionMgr::RestrictConnections(nsConnectionEntry *ent,
// don't create any new ssl connections until the result of the
// negotiation is known.
bool doRestrict = ent->mConnInfo->FirstHopSSL() &&
gHttpHandler->IsSpdyEnabled() &&
((!ent->mTestedSpdy && !ignorePossibleSpdyConnections) ||
ent->mUsingSpdy) &&
(ent->mHalfOpens.Length() || ent->mActiveConns.Length());
bool doRestrict =
ent->mConnInfo->FirstHopSSL() && gHttpHandler->IsSpdyEnabled() &&
ent->mUsingSpdy && (ent->mHalfOpens.Length() || ent->mActiveConns.Length());
// If there are no restrictions, we are done
if (!doRestrict)
@ -1106,8 +1128,9 @@ nsHttpConnectionMgr::RestrictConnections(nsConnectionEntry *ent,
// If the restriction is based on a tcp handshake in progress
// let that connect and then see if it was SPDY or not
if (ent->UnconnectedHalfOpens() && !ignorePossibleSpdyConnections)
if (ent->UnconnectedHalfOpens()) {
return true;
}
// There is a concern that a host is using a mix of HTTP/1 and SPDY.
// In that case we don't want to restrict connections just because
@ -2416,9 +2439,7 @@ nsHttpConnectionMgr::OnMsgPruneDeadConnections(int32_t, ARefBase *)
ent->mActiveConns.Length() == 0 &&
ent->mHalfOpens.Length() == 0 &&
ent->mPendingQ.Length() == 0 &&
((!ent->mTestedSpdy && !ent->mUsingSpdy) ||
!gHttpHandler->IsSpdyEnabled() ||
mCT.Count() > 300)) {
(!ent->mUsingSpdy || mCT.Count() > 300)) {
LOG((" removing empty connection entry\n"));
iter.Remove();
continue;
@ -2732,14 +2753,14 @@ nsHttpConnectionMgr::TimeoutTick()
LOG(("nsHttpConnectionMgr::TimeoutTick active=%d\n", mNumActiveConns));
// The next tick will be between 1 second and 1 hr
// Set it to the max value here, and the TimeoutTickCB()s can
// Set it to the max value here, and the TimeoutTick()s can
// reduce it to their local needs.
mTimeoutTickNext = 3600; // 1hr
for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
nsAutoPtr<nsConnectionEntry>& ent = iter.Data();
LOG(("nsHttpConnectionMgr::TimeoutTickCB() this=%p host=%s "
LOG(("nsHttpConnectionMgr::TimeoutTick() this=%p host=%s "
"idle=%d active=%d half-len=%d pending=%d\n",
this, ent->mConnInfo->Origin(), ent->mIdleConns.Length(),
ent->mActiveConns.Length(), ent->mHalfOpens.Length(),
@ -2880,14 +2901,12 @@ nsHttpConnectionMgr::OnMsgSpeculativeConnect(int32_t, ARefBase *param)
uint32_t parallelSpeculativeConnectLimit =
gHttpHandler->ParallelSpeculativeConnectLimit();
bool ignorePossibleSpdyConnections = false;
bool ignoreIdle = false;
bool isFromPredictor = false;
bool allow1918 = false;
if (args->mOverridesOK) {
parallelSpeculativeConnectLimit = args->mParallelSpeculativeConnectLimit;
ignorePossibleSpdyConnections = args->mIgnorePossibleSpdyConnections;
ignoreIdle = args->mIgnoreIdle;
isFromPredictor = args->mIsFromPredictor;
allow1918 = args->mAllow1918;
@ -2897,12 +2916,12 @@ nsHttpConnectionMgr::OnMsgSpeculativeConnect(int32_t, ARefBase *param)
if (mNumHalfOpenConns < parallelSpeculativeConnectLimit &&
((ignoreIdle && (ent->mIdleConns.Length() < parallelSpeculativeConnectLimit)) ||
!ent->mIdleConns.Length()) &&
!(keepAlive && RestrictConnections(ent, ignorePossibleSpdyConnections)) &&
!(keepAlive && RestrictConnections(ent)) &&
!AtActiveConnectionLimit(ent, args->mTrans->Caps())) {
CreateTransport(ent, args->mTrans, args->mTrans->Caps(), true, isFromPredictor, allow1918);
}
else {
LOG((" Transport not created due to existing connection count\n"));
} else {
LOG(("OnMsgSpeculativeConnect Transport "
"not created due to existing connection count\n"));
}
}
@ -3137,6 +3156,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),
@ -3160,7 +3181,7 @@ nsHttpConnectionMgr::nsHalfOpenSocket::SetupBackupTimer()
{
uint16_t timeout = gHttpHandler->GetIdleSynTimeout();
MOZ_ASSERT(!mSynTimer, "timer already initd");
if (timeout && !mTransaction->IsDone()) {
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
@ -3174,10 +3195,8 @@ nsHttpConnectionMgr::nsHalfOpenSocket::SetupBackupTimer()
mSynTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT);
LOG(("nsHalfOpenSocket::SetupBackupTimer() [this=%p]", this));
}
}
else if (timeout) {
LOG(("nsHalfOpenSocket::SetupBackupTimer() [this=%p],"
" transaction already done!", this));
} else if (timeout) {
LOG(("nsHalfOpenSocket::SetupBackupTimer() [this=%p], did not arm\n", this));
}
}
@ -3197,8 +3216,10 @@ nsHttpConnectionMgr::nsHalfOpenSocket::CancelBackupTimer()
void
nsHttpConnectionMgr::nsHalfOpenSocket::Abandon()
{
LOG(("nsHalfOpenSocket::Abandon [this=%p ent=%s]",
this, mEnt->mConnInfo->Origin()));
LOG(("nsHalfOpenSocket::Abandon [this=%p ent=%s] %p %p %p %p",
this, mEnt->mConnInfo->Origin(),
mSocketTransport.get(), mBackupTransport.get(),
mStreamOut.get(), mBackupStreamOut.get()));
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
@ -3255,6 +3276,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");
SetupBackupStreams();
@ -3308,8 +3331,9 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out)
mStreamOut = nullptr;
mStreamIn = nullptr;
mSocketTransport = nullptr;
}
else {
} 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,
@ -3325,6 +3349,9 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out)
mBackupStreamOut = nullptr;
mBackupStreamIn = nullptr;
mBackupTransport = nullptr;
} else {
MOZ_ASSERT(false, "unexpected stream");
rv = NS_ERROR_UNEXPECTED;
}
if (NS_FAILED(rv)) {
@ -3464,7 +3491,7 @@ nsHttpConnectionMgr::nsHalfOpenSocket::OnTransportStatus(nsITransport *trans,
// this half open socket has already been abandoned. It may happen
// when we get this notification right between main-thread calls to
// nsHttpConnectionMgr::Shutdown and nsSocketTransportService::Shutdown
// where the first abandones all half open socket instances and only
// where the first abandons all half open socket instances and only
// after that the second stops the socket thread.
if (mEnt && !mBackupTransport && !mSynTimer)
SetupBackupTimer();
@ -3537,7 +3564,6 @@ nsConnectionEntry::nsConnectionEntry(nsHttpConnectionInfo *ci)
, mGreenDepth(kPipelineOpen)
, mPipeliningPenalty(0)
, mUsingSpdy(false)
, mTestedSpdy(false)
, mInPreferredHash(false)
, mPreferIPv4(false)
, mPreferIPv6(false)
@ -3939,7 +3965,6 @@ nsHttpConnectionMgr::MoveToWildCardConnEntry(nsHttpConnectionInfo *specificCI,
return;
}
wcEnt->mUsingSpdy = true;
wcEnt->mTestedSpdy = true;
LOG(("nsHttpConnectionMgr::MakeConnEntryWildCard ent %p "
"idle=%d active=%d half=%d pending=%d\n", ent,

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

@ -371,12 +371,6 @@ private:
// connection is currently using spdy.
bool mUsingSpdy : 1;
// mTestedSpdy is set after NPN negotiation has occurred and we know
// with confidence whether a host speaks spdy or not (which is reflected
// in mUsingSpdy). Before mTestedSpdy is set, handshake parallelism is
// minimized so that we can multiplex on a single spdy connection.
bool mTestedSpdy : 1;
bool mInPreferredHash : 1;
// Flags to remember our happy-eyeballs decision.
@ -531,7 +525,7 @@ private:
nsresult BuildPipeline(nsConnectionEntry *,
nsAHttpTransaction *,
nsHttpPipeline **);
bool RestrictConnections(nsConnectionEntry *, bool = false);
bool RestrictConnections(nsConnectionEntry *);
nsresult ProcessNewTransaction(nsHttpTransaction *);
nsresult EnsureSocketThreadTarget();
void ClosePersistentConnections(nsConnectionEntry *ent);