Bug 1365306 - Remove net::ThrottlingService, don't suspend/resume download channels on page load. r=hurley

This commit is contained in:
Honza Bambas 2017-05-18 14:09:00 -04:00
parent 56b8e8c07e
commit 5f3173e90f
23 changed files with 6 additions and 734 deletions

View File

@ -7609,10 +7609,6 @@ nsresult
nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
nsIChannel* aChannel, nsresult aStatus)
{
// We can release any pressure we may have had on the throttling service and
// let background channels continue.
mThrottler.reset();
if (!aChannel) {
return NS_ERROR_NULL_POINTER;
}
@ -10799,16 +10795,6 @@ nsDocShell::InternalLoad(nsIURI* aURI,
net::PredictorPredict(aURI, nullptr,
nsINetworkPredictor::PREDICT_LOAD, attrs, nullptr);
// Increase pressure on the throttling service so background channels will be
// appropriately de-prioritized. We need to explicitly check for http[s] here
// so that we don't throttle while loading, say, about:blank.
bool isHTTP, isHTTPS;
aURI->SchemeIs("http", &isHTTP);
aURI->SchemeIs("https", &isHTTPS);
if (isHTTP || isHTTPS) {
mThrottler.reset(new mozilla::net::Throttler());
}
nsCOMPtr<nsIRequest> req;
rv = DoURILoad(aURI, aOriginalURI, aLoadReplace, aReferrer,
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),

View File

@ -60,7 +60,6 @@
#include "nsRect.h"
#include "Units.h"
#include "nsIDeprecationWarner.h"
#include "nsIThrottlingService.h"
namespace mozilla {
enum class TaskCategory;
@ -1101,9 +1100,6 @@ public:
InterfaceRequestorProxy() {}
nsWeakPtr mWeakPtr;
};
private:
mozilla::UniquePtr<mozilla::net::Throttler> mThrottler;
};
#endif /* nsDocShell_h__ */

View File

@ -1,440 +0,0 @@
/* vim: set ts=2 sts=2 et sw=2: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Things to think about
// * do we need to be multithreaded, or is mt-only ok?
#include "ThrottlingService.h"
#include "nsIHttpChannel.h"
#include "nsIObserverService.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/net/NeckoChild.h"
namespace mozilla {
namespace net{
static const char kEnabledPref[] = "network.throttle.enable";
static const bool kDefaultEnabled = true;
// During a page load presure, every channel that is marked as Throttleable
// is being periodically suspended and resumed for the suspend-for and
// resume-for intervals respectively. This gives more bandwidth to other
// more priority responses.
static const char kSuspendPeriodPref[] = "network.throttle.suspend-for";
static const uint32_t kDefaultSuspendPeriod = 3000;
static const char kResumePeriodPref[] = "network.throttle.resume-for";
static const uint32_t kDefaultResumePeriod = 200;
NS_IMPL_ISUPPORTS(ThrottlingService, nsIThrottlingService, nsIObserver, nsITimerCallback)
ThrottlingService::ThrottlingService()
:mEnabled(kDefaultEnabled)
,mInitCalled(false)
,mSuspended(false)
,mPressureCount(0)
,mSuspendPeriod(kDefaultSuspendPeriod)
,mResumePeriod(kDefaultResumePeriod)
,mIteratingHash(false)
{
}
ThrottlingService::~ThrottlingService()
{
Shutdown();
}
nsresult
ThrottlingService::Init()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mInitCalled);
mInitCalled = true;
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) {
return NS_ERROR_UNEXPECTED;
}
nsresult rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
NS_ENSURE_SUCCESS(rv, rv);
mEnabled = Preferences::GetBool(kEnabledPref, kDefaultEnabled);
rv = Preferences::AddStrongObserver(this, kEnabledPref);
NS_ENSURE_SUCCESS(rv, rv);
Preferences::AddUintVarCache(&mSuspendPeriod, kSuspendPeriodPref, kDefaultSuspendPeriod);
Preferences::AddUintVarCache(&mResumePeriod, kResumePeriodPref, kDefaultResumePeriod);
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
return NS_OK;
}
void
ThrottlingService::Shutdown()
{
if (!mInitCalled) {
return;
}
if (mTimer) {
mTimer->Cancel();
}
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
}
Preferences::RemoveObserver(this, kEnabledPref);
MaybeResumeAll();
mChannelHash.Clear();
}
nsresult
ThrottlingService::Create(nsISupports *outer, const nsIID& iid, void **result)
{
MOZ_ASSERT(NS_IsMainThread());
if (outer != nullptr) {
return NS_ERROR_NO_AGGREGATION;
}
RefPtr<ThrottlingService> svc = new ThrottlingService();
if (!IsNeckoChild()) {
// We only need to do any work on the parent, so only bother initializing
// there. Child-side, we'll just error out since we only deal with parent
// channels.)
nsresult rv = svc->Init();
NS_ENSURE_SUCCESS(rv, rv);
}
return svc->QueryInterface(iid, result);
}
// nsIThrottlingService
nsresult
ThrottlingService::AddChannel(nsIHttpChannel *channel)
{
MOZ_ASSERT(NS_IsMainThread());
// We don't check mEnabled, because we always want to put channels in the hash
// to avoid potential inconsistencies in the case where the user changes the
// enabled pref at run-time.
if (IsNeckoChild()) {
return NS_ERROR_NOT_AVAILABLE;
}
uint64_t key;
nsresult rv = channel->GetChannelId(&key);
NS_ENSURE_SUCCESS(rv, rv);
if (mChannelHash.Get(key, nullptr)) {
// We already have this channel under our control, not adding it again.
return NS_OK;
}
if (!mIteratingHash) {
// This should be the common case, and as such is easy to handle
mChannelHash.Put(key, channel);
if (mSuspended) {
channel->Suspend();
}
} else {
// This gets tricky - we've somehow re-entrantly gotten here through the
// hash iteration in one of MaybeSuspendAll or MaybeResumeAll. Keep track
// of the fact that this add came in now, and once we're done iterating, we
// can add this into the hash. This avoids unexpectedly modifying the hash
// while it's being iterated over, which could lead to inconsistencies.
mChannelsToAddRemove.AppendElement(channel);
mChannelIsAdd.AppendElement(true);
}
return NS_OK;
}
nsresult
ThrottlingService::RemoveChannel(nsIHttpChannel *channel)
{
MOZ_ASSERT(NS_IsMainThread());
// Just like above, don't worry about mEnabled to avoid inconsistencies when
// the pref changes at run-time
if (IsNeckoChild()) {
return NS_ERROR_NOT_AVAILABLE;
}
uint64_t key;
nsresult rv = channel->GetChannelId(&key);
NS_ENSURE_SUCCESS(rv, rv);
if (!mChannelHash.Get(key, nullptr)) {
// TODO - warn?
return NS_ERROR_ILLEGAL_VALUE;
}
if (!mIteratingHash) {
// This should be the common case, and easy to handle.
mChannelHash.Remove(key);
if (mSuspended) {
// This channel is no longer under our control for suspend/resume, but
// we've suspended it. Time to let it go.
channel->Resume();
}
} else {
// This gets tricky - we've somehow re-entrantly gotten here through the
// hash iteration in one of MaybeSuspendAll or MaybeResumeAll. Keep track
// of the fact that this add came in now, and once we're done iterating, we
// can add this into the hash. This avoids unexpectedly modifying the hash
// while it's being iterated over, which could lead to inconsistencies.
mChannelsToAddRemove.AppendElement(channel);
mChannelIsAdd.AppendElement(false);
}
return NS_OK;
}
nsresult
ThrottlingService::IncreasePressure()
{
MOZ_ASSERT(NS_IsMainThread());
// Just like add/removing channels, we don't check mEnabled here in order to
// avoid inconsistencies that could occur if the pref is flipped at runtime
if (IsNeckoChild()) {
return NS_ERROR_NOT_AVAILABLE;
}
if (mPressureCount++ == 0) {
MOZ_ASSERT(!mSuspended, "Suspended with 0 pressure?");
MaybeSuspendAll();
if (mSuspended) {
// MaybeSuspendAll() may not actually suspend things, and we only want to
// bother setting a timer to resume if we actually suspended.
mTimer->InitWithCallback(this, mSuspendPeriod, nsITimer::TYPE_ONE_SHOT);
}
}
return NS_OK;
}
nsresult
ThrottlingService::DecreasePressure()
{
MOZ_ASSERT(NS_IsMainThread());
// Just like add/removing channels, we don't check mEnabled here in order to
// avoid inconsistencies that could occur if the pref is flipped at runtime
if (IsNeckoChild()) {
return NS_ERROR_NOT_AVAILABLE;
}
MOZ_ASSERT(mPressureCount > 0, "Unbalanced throttle pressure");
if (--mPressureCount == 0) {
MaybeResumeAll();
mTimer->Cancel();
}
return NS_OK;
}
// nsIObserver
nsresult
ThrottlingService::Observe(nsISupports *subject, const char *topic,
const char16_t *data_unicode)
{
MOZ_ASSERT(!IsNeckoChild());
MOZ_ASSERT(NS_IsMainThread());
if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, topic)) {
Shutdown();
} else if (!strcmp("nsPref:changed", topic)) {
mEnabled = Preferences::GetBool(kEnabledPref, mEnabled);
if (mEnabled && mPressureCount) {
// We weren't enabled, but we are now, AND we're under pressure. Go ahead
// and suspend things.
MaybeSuspendAll();
if (mSuspended) {
mTimer->InitWithCallback(this, mSuspendPeriod, nsITimer::TYPE_ONE_SHOT);
}
} else if (!mEnabled) {
// We were enabled, but we aren't any longer. Make sure we aren't
// suspending channels and that we don't have any timer that wants to
// change things unexpectedly.
mTimer->Cancel();
MaybeResumeAll();
}
}
return NS_OK;
}
// nsITimerCallback
nsresult
ThrottlingService::Notify(nsITimer *timer)
{
MOZ_ASSERT(!IsNeckoChild());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(timer == mTimer);
if (mSuspended) {
MaybeResumeAll();
// Always try to resume if we were suspended, but only time-limit the
// resumption if we're under pressure and we're enabled. If either of those
// conditions is false, it doesn't make any sense to set a timer to suspend
// things when we don't want to be suspended anyway.
if (mPressureCount && mEnabled) {
mTimer->InitWithCallback(this, mResumePeriod, nsITimer::TYPE_ONE_SHOT);
}
} else if (mPressureCount) {
MaybeSuspendAll();
if (mSuspended) {
// MaybeSuspendAll() may not actually suspend, and it only makes sense to
// set a timer to resume if we actually suspended the channels.
mTimer->InitWithCallback(this, mSuspendPeriod, nsITimer::TYPE_ONE_SHOT);
}
}
return NS_OK;
}
// Internal methods
void
ThrottlingService::MaybeSuspendAll()
{
MOZ_ASSERT(!IsNeckoChild());
MOZ_ASSERT(NS_IsMainThread());
if (!mEnabled) {
// We don't actually suspend when disabled, even though it's possible we get
// called in that state in order to avoid inconsistencies in the hash and
// the count if the pref changes at runtime.
return;
}
if (mSuspended) {
// Already suspended, nothing to do!
return;
}
mSuspended = true;
IterateHash([](ChannelHash::Iterator &iter) -> void {
const nsCOMPtr<nsIHttpChannel> channel = iter.UserData();
channel->Suspend();
});
}
void
ThrottlingService::MaybeResumeAll()
{
MOZ_ASSERT(!IsNeckoChild());
MOZ_ASSERT(NS_IsMainThread());
if (!mSuspended) {
// Already resumed, nothing to do!
return;
}
mSuspended = false;
IterateHash([](ChannelHash::Iterator &iter) -> void {
const nsCOMPtr<nsIHttpChannel> channel = iter.UserData();
channel->Resume();
});
}
void
ThrottlingService::IterateHash(void (* callback)(ChannelHash::Iterator &iter))
{
MOZ_ASSERT(!mIteratingHash);
mIteratingHash = true;
for (ChannelHash::Iterator iter = mChannelHash.ConstIter(); !iter.Done(); iter.Next()) {
callback(iter);
}
mIteratingHash = false;
HandleExtraAddRemove();
}
void
ThrottlingService::HandleExtraAddRemove()
{
MOZ_ASSERT(!mIteratingHash);
MOZ_ASSERT(mChannelsToAddRemove.Length() == mChannelIsAdd.Length());
nsCOMArray<nsIHttpChannel> channelsToAddRemove;
channelsToAddRemove.SwapElements(mChannelsToAddRemove);
nsTArray<bool> channelIsAdd;
channelIsAdd.SwapElements(mChannelIsAdd);
for (size_t i = 0; i < channelsToAddRemove.Length(); ++i) {
if (channelIsAdd[i]) {
AddChannel(channelsToAddRemove[i]);
} else {
RemoveChannel(channelsToAddRemove[i]);
}
}
channelsToAddRemove.Clear();
channelIsAdd.Clear();
}
// The publicly available way to throttle things
Throttler::Throttler()
{
MOZ_ASSERT(NS_IsMainThread());
if (IsNeckoChild()) {
if (gNeckoChild) {
// The child object may have already gone away, so we need to guard
// guard against deref'ing a nullptr here. If that's what happened, then
// our pageload won't be continuing anyway, so what we do is pretty much
// irrelevant.
gNeckoChild->SendIncreaseThrottlePressure();
}
} else {
mThrottlingService = do_GetService("@mozilla.org/network/throttling-service;1");
mThrottlingService->IncreasePressure();
}
}
Throttler::~Throttler()
{
MOZ_ASSERT(NS_IsMainThread());
if (IsNeckoChild()) {
if (gNeckoChild) {
// The child object may have already gone away, so we need to guard
// guard against deref'ing a nullptr here. If that's what happened, then
// NeckoParent::ActorDestroy will take care of releasing the pressure we
// created.
gNeckoChild->SendDecreaseThrottlePressure();
}
} else {
MOZ_RELEASE_ASSERT(mThrottlingService);
mThrottlingService->DecreasePressure();
mThrottlingService = nullptr;
}
}
}
}

View File

@ -1,67 +0,0 @@
/* vim: set ts=2 sts=2 et sw=2: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla__net__ThrottlingService_h
#define mozilla__net__ThrottlingService_h
#include "nsIThrottlingService.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "nsInterfaceHashtable.h"
#include "nsIObserver.h"
#include "nsITimer.h"
class nsIHttpChannel;
namespace mozilla {
namespace net {
class ThrottlingService : public nsIThrottlingService
, public nsIObserver
, public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITHROTTLINGSERVICE
NS_DECL_NSIOBSERVER
NS_DECL_NSITIMERCALLBACK
ThrottlingService();
nsresult Init();
void Shutdown();
static nsresult Create(nsISupports *outer, const nsIID& iid, void **result);
private:
virtual ~ThrottlingService();
void MaybeSuspendAll();
void MaybeResumeAll();
void HandleExtraAddRemove();
bool mEnabled;
bool mInitCalled;
bool mSuspended;
uint32_t mPressureCount;
uint32_t mSuspendPeriod; // How long we should Suspend() channels for
uint32_t mResumePeriod; // How long we should Resume() channels for
nsCOMPtr<nsITimer> mTimer;
typedef nsInterfaceHashtable<nsUint64HashKey, nsIHttpChannel> ChannelHash;
ChannelHash mChannelHash;
// Used to avoid inconsistencies in the hash and the suspend/resume count of
// channels. See comments in AddChannel and RemoveChannel for details.
void IterateHash(void (* callback)(ChannelHash::Iterator &iter));
bool mIteratingHash;
nsCOMArray<nsIHttpChannel> mChannelsToAddRemove;
nsTArray<bool> mChannelIsAdd;
};
} // ::mozilla::net
} // ::mozilla
#endif // mozilla__net__ThrottlingService_h

View File

@ -117,7 +117,6 @@ XPIDL_SOURCES += [
'nsIThreadRetargetableRequest.idl',
'nsIThreadRetargetableStreamListener.idl',
'nsIThrottledInputChannel.idl',
'nsIThrottlingService.idl',
'nsITimedChannel.idl',
'nsITLSServerSocket.idl',
'nsITraceableChannel.idl',
@ -250,7 +249,6 @@ UNIFIED_SOURCES += [
'StreamingProtocolService.cpp',
'TCPFastOpenLayer.cpp',
'ThrottleQueue.cpp',
'ThrottlingService.cpp',
'Tickler.cpp',
'TLSServerSocket.cpp',
]

View File

@ -1,37 +0,0 @@
/* vim: set ts=2 sts=2 et sw=2: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIHttpChannel;
[builtinclass, uuid(c755ef98-b749-4f30-a658-1e6110013a66)]
interface nsIThrottlingService : nsISupports
{
void addChannel(in nsIHttpChannel channel);
void removeChannel(in nsIHttpChannel channel);
/* Don't call these directly, use mozilla::net::Throttler instead! */
void increasePressure();
void decreasePressure();
};
%{C++
namespace mozilla {
namespace net {
class Throttler
{
public:
Throttler();
~Throttler();
private:
nsCOMPtr<nsIThrottlingService> mThrottlingService;
};
} // ::mozilla::net
} // ::mozilla
%}

View File

@ -494,17 +494,6 @@
{0x93, 0x30, 0x18, 0x58, 0xb9, 0x9a, 0xce, 0x69} \
}
// service implementing nsIThrottlingService
#define NS_THROTTLINGSERVICE_CONTRACTID \
"@mozilla.org/network/throttling-service;1"
#define NS_THROTTLINGSERVICE_CID \
{ /* c1c48f2b-cb9c-415e-b4f9-5e4c3476ca86 */ \
0xc1c48f2b, \
0xcb9c, \
0x415e, \
{0xb4, 0xf9, 0x5e, 0x4c, 0x34, 0x76, 0xca, 0x86} \
}
/******************************************************************************
* netwerk/cache/ classes
*/

View File

@ -38,7 +38,6 @@
#include "nsCategoryCache.h"
#include "nsIContentSniffer.h"
#include "Predictor.h"
#include "ThrottlingService.h"
#include "nsIThreadPool.h"
#include "mozilla/net/NeckoChild.h"
@ -875,7 +874,6 @@ NS_DEFINE_NAMED_CID(NS_REQUESTCONTEXTSERVICE_CID);
#ifdef BUILD_NETWORK_INFO_SERVICE
NS_DEFINE_NAMED_CID(NETWORKINFOSERVICE_CID);
#endif // BUILD_NETWORK_INFO_SERVICE
NS_DEFINE_NAMED_CID(NS_THROTTLINGSERVICE_CID);
static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
{ &kNS_IOSERVICE_CID, false, nullptr, nsIOServiceConstructor },
@ -1029,7 +1027,6 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
#ifdef BUILD_NETWORK_INFO_SERVICE
{ &kNETWORKINFOSERVICE_CID, false, nullptr, nsNetworkInfoServiceConstructor },
#endif
{ &kNS_THROTTLINGSERVICE_CID, false, nullptr, mozilla::net::ThrottlingService::Create },
{ nullptr }
};
@ -1188,7 +1185,6 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
#ifdef BUILD_NETWORK_INFO_SERVICE
{ NETWORKINFOSERVICE_CONTRACT_ID, &kNETWORKINFOSERVICE_CID },
#endif
{ NS_THROTTLINGSERVICE_CONTRACTID, &kNS_THROTTLINGSERVICE_CID },
{ nullptr }
};

View File

@ -48,7 +48,6 @@
#include "nsINetworkPredictor.h"
#include "nsINetworkPredictorVerifier.h"
#include "nsISpeculativeConnect.h"
#include "nsIThrottlingService.h"
#include "nsNetUtil.h"
using mozilla::OriginAttributes;
@ -946,23 +945,6 @@ NeckoParent::RecvRemoveRequestContext(const uint64_t& rcid)
return IPC_OK();
}
mozilla::ipc::IPCResult
NeckoParent::RecvIncreaseThrottlePressure()
{
mThrottlers.AppendElement(mozilla::UniquePtr<mozilla::net::Throttler>(new mozilla::net::Throttler));
return IPC_OK();
}
mozilla::ipc::IPCResult
NeckoParent::RecvDecreaseThrottlePressure()
{
MOZ_ASSERT(!mThrottlers.IsEmpty());
// We do this because we don't actually care which throttler gets removed,
// just that one of them does.
mThrottlers.RemoveElementAt(0);
return IPC_OK();
}
mozilla::ipc::IPCResult
NeckoParent::RecvNotifyCurrentTopLevelOuterContentWindowId(const uint64_t& aWindowId)
{

View File

@ -10,7 +10,6 @@
#include "mozilla/net/NeckoCommon.h"
#include "nsIAuthPrompt2.h"
#include "nsINetworkPredictor.h"
#include "nsIThrottlingService.h"
#include "nsNetUtil.h"
#ifndef mozilla_net_NeckoParent_h
@ -236,14 +235,7 @@ protected:
virtual mozilla::ipc::IPCResult RecvRemoveRequestContext(const uint64_t& rcid) override;
/* Throttler messages */
virtual mozilla::ipc::IPCResult RecvIncreaseThrottlePressure() override;
virtual mozilla::ipc::IPCResult RecvDecreaseThrottlePressure() override;
virtual mozilla::ipc::IPCResult
RecvNotifyCurrentTopLevelOuterContentWindowId(const uint64_t& aWindowId) override;
private:
nsTArray<mozilla::UniquePtr<mozilla::net::Throttler>> mThrottlers;
virtual mozilla::ipc::IPCResult RecvNotifyCurrentTopLevelOuterContentWindowId(const uint64_t& aWindowId) override;
};
} // namespace net

View File

@ -125,12 +125,6 @@ parent:
async PStunAddrsRequest();
/**
* Throttling of channels
*/
async IncreaseThrottlePressure();
async DecreaseThrottlePressure();
prio(high) async NotifyCurrentTopLevelOuterContentWindowId(uint64_t windowId);
child:

View File

@ -4248,11 +4248,5 @@ Http2Session::RealJoinConnection(const nsACString &hostname, int32_t port,
return joinedReturn;
}
void
Http2Session::ThrottleResponse(bool aThrottle)
{
// Response throttling on an h2 connection will be implemented later.
}
} // namespace net
} // namespace mozilla

View File

@ -52,7 +52,6 @@ public:
uint32_t SpdyVersion() override;
bool TestJoinConnection(const nsACString &hostname, int32_t port) override;
bool JoinConnection(const nsACString &hostname, int32_t port) override;
void ThrottleResponse(bool aThrottle) override;
// When the connection is active this is called up to once every 1 second
// return the interval (in seconds) that the connection next wants to

View File

@ -62,7 +62,6 @@
#include "nsIXULRuntime.h"
#include "nsICacheInfoChannel.h"
#include "nsIDOMWindowUtils.h"
#include "nsIThrottlingService.h"
#include <algorithm>
#include "HttpBaseChannel.h"
@ -3071,13 +3070,6 @@ HttpBaseChannel::ReleaseListeners()
{
MOZ_ASSERT(NS_IsMainThread(), "Should only be called on the main thread.");
if (mClassOfService & nsIClassOfService::Throttleable) {
nsIThrottlingService *throttler = gHttpHandler->GetThrottlingService();
if (throttler) {
throttler->RemoveChannel(this);
}
}
mListener = nullptr;
mListenerContext = nullptr;
mCallbacks = nullptr;

View File

@ -146,14 +146,6 @@ public:
// nsHttp.h version
virtual uint32_t Version() = 0;
// Throttling control, can be called only on the socket thread. HTTP/1
// implementation effects whether we AsyncWait on the socket input stream
// after reading data. This doesn't have a counter-like logic, hence
// calling it with aThrottle = false will re-enable read from the socket
// immediately. Calling more than once with the same argument value has
// no effect.
virtual void ThrottleResponse(bool aThrottle) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpConnection, NS_AHTTPCONNECTION_IID)

View File

@ -107,7 +107,6 @@
#include "HSTSPrimerListener.h"
#include "CacheStorageService.h"
#include "HttpChannelParent.h"
#include "nsIThrottlingService.h"
#include "nsIBufferedStreams.h"
#include "nsIFileStreams.h"
#include "nsIMIMEInputStream.h"
@ -711,7 +710,7 @@ nsHttpChannel::ContinueConnect()
while (suspendCount--)
mTransactionPump->Suspend();
if (mSuspendCount && mClassOfService & nsIClassOfService::Throttleable) {
if (mClassOfService & nsIClassOfService::Throttleable) {
gHttpHandler->ThrottleTransaction(mTransaction, true);
}
@ -6627,18 +6626,9 @@ nsHttpChannel::OnClassOfServiceUpdated()
{
bool throttleable = !!(mClassOfService & nsIClassOfService::Throttleable);
if (mSuspendCount && mTransaction) {
if (mTransaction) {
gHttpHandler->ThrottleTransaction(mTransaction, throttleable);
}
nsIThrottlingService *throttler = gHttpHandler->GetThrottlingService();
if (throttler) {
if (throttleable) {
throttler->AddChannel(this);
} else {
throttler->RemoveChannel(this);
}
}
}
NS_IMETHODIMP

View File

@ -86,8 +86,6 @@ nsHttpConnection::nsHttpConnection()
, mContentBytesWritten0RTT(0)
, mEarlyDataNegotiated(false)
, mDid0RTTSpdy(false)
, mResponseThrottled(false)
, mResumeRecvOnUnthrottle(false)
, mFastOpen(false)
, mFastOpenStatus(TFO_NOT_TRIED)
, mForceSendDuringFastOpenPending(false)
@ -1471,22 +1469,6 @@ nsHttpConnection::ResumeRecv()
return NS_OK;
}
// mResponseThrottled is an indication from above layers to stop reading
// the socket.
if (mResponseThrottled) {
mResumeRecvOnUnthrottle = true;
if (mSocketIn) {
LOG((" throttled, waiting for closure only"));
return mSocketIn->AsyncWait(this,
nsIAsyncInputStream::WAIT_CLOSURE_ONLY,
0, nullptr);
}
LOG((" throttled, and no socket input stream"));
NS_NOTREACHED("no socket input stream");
return NS_OK;
}
// the mLastReadTime timestamp is used for finding slowish readers
// and can be pretty sensitive. For that reason we actually reset it
// when we ask to read (resume recv()) so that when we get called back
@ -2165,32 +2147,6 @@ nsHttpConnection::DisableTCPKeepalives()
return NS_OK;
}
void nsHttpConnection::ThrottleResponse(bool aThrottle)
{
LOG(("nsHttpConnection::ThrottleResponse this=%p, throttle=%d", this, aThrottle));
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
if (aThrottle) {
mResponseThrottled = true;
return;
}
mResponseThrottled = false;
if (!mResumeRecvOnUnthrottle) {
// We didn't get to the point when ResumeRecv was called
// during the throttle period, nothing to do.
return;
}
mResumeRecvOnUnthrottle = false;
nsresult rv = ResumeRecv();
if (NS_FAILED(rv)) {
CloseTransaction(mTransaction, rv);
}
}
//-----------------------------------------------------------------------------
// nsHttpConnection::nsISupports
//-----------------------------------------------------------------------------

View File

@ -231,8 +231,6 @@ public:
bool TestJoinConnection(const nsACString &hostname, int32_t port);
bool JoinConnection(const nsACString &hostname, int32_t port);
void ThrottleResponse(bool aThrottle);
void SetFastOpenStatus(uint8_t tfoStatus) {
mFastOpenStatus = tfoStatus;
}
@ -396,13 +394,6 @@ private:
nsCString mEarlyNegotiatedALPN;
bool mDid0RTTSpdy;
// Reflects throttling request, effects if we resume read from the socket.
// Accessed only on the socket thread.
bool mResponseThrottled;
// A read from the socket was requested while we where throttled, means
// to ResumeRecv() when untrottled again. Only accessed on the socket thread.
bool mResumeRecvOnUnthrottle;
bool mFastOpen;
uint8_t mFastOpenStatus;

View File

@ -1640,7 +1640,6 @@ class ConnectionHandle : public nsAHttpConnection
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSAHTTPCONNECTION(mConn)
virtual void ThrottleResponse(bool aThrottle) override;
explicit ConnectionHandle(nsHttpConnection *conn) : mConn(conn) { }
void Reset() { mConn = nullptr; }
@ -1655,13 +1654,6 @@ nsHttpConnectionMgr::MakeConnectionHandle(nsHttpConnection *aWrapped)
return new ConnectionHandle(aWrapped);
}
void ConnectionHandle::ThrottleResponse(bool aThrottle)
{
if (mConn) {
mConn->ThrottleResponse(aThrottle);
}
}
ConnectionHandle::~ConnectionHandle()
{
if (mConn) {

View File

@ -53,7 +53,6 @@
#include "nsComponentManagerUtils.h"
#include "nsSocketTransportService2.h"
#include "nsIOService.h"
#include "nsIThrottlingService.h"
#include "nsISupportsPrimitives.h"
#include "nsIXULRuntime.h"
#include "nsCharSeparatedTokenizer.h"
@ -715,17 +714,6 @@ nsHttpHandler::GetIOService(nsIIOService** result)
return NS_OK;
}
nsIThrottlingService *
nsHttpHandler::GetThrottlingService()
{
if (!mThrottlingService) {
nsCOMPtr<nsIThrottlingService> service = do_GetService(NS_THROTTLINGSERVICE_CONTRACTID);
mThrottlingService = new nsMainThreadPtrHolder<nsIThrottlingService>(service);
}
return mThrottlingService;
}
uint32_t
nsHttpHandler::Get32BitsOfPseudoRandom()
{

View File

@ -27,7 +27,6 @@ class nsIIOService;
class nsIRequestContextService;
class nsISiteSecurityService;
class nsIStreamConverterService;
class nsIThrottlingService;
namespace mozilla {
@ -296,7 +295,6 @@ public:
MOZ_MUST_USE nsresult GetIOService(nsIIOService** service);
nsICookieService * GetCookieService(); // not addrefed
nsISiteSecurityService * GetSSService();
nsIThrottlingService * GetThrottlingService();
// callable from socket thread only
uint32_t Get32BitsOfPseudoRandom();
@ -412,7 +410,6 @@ private:
nsMainThreadPtrHandle<nsIStreamConverterService> mStreamConvSvc;
nsMainThreadPtrHandle<nsICookieService> mCookieService;
nsMainThreadPtrHandle<nsISiteSecurityService> mSSService;
nsMainThreadPtrHandle<nsIThrottlingService> mThrottlingService;
// the authentication credentials cache
nsHttpAuthCache mAuthCache;

View File

@ -159,12 +159,7 @@ void nsHttpTransaction::ThrottleResponse(bool aThrottle)
{
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
// Just in case we suspend, get a connection, release a connection, get another connection.
mThrottleResponse = aThrottle;
if (mConnection) {
mConnection->ThrottleResponse(aThrottle);
}
}
nsHttpTransaction::~nsHttpTransaction()
@ -479,10 +474,6 @@ nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
MutexAutoLock lock(mLock);
mConnection = conn;
}
if (conn && mThrottleResponse) {
gHttpHandler->ThrottleTransaction(this, true);
}
}
void

View File

@ -313,6 +313,7 @@ private:
Atomic<bool, ReleaseAcquire> mResponseIsComplete;
// If true, this transaction was asked to stop receiving the response.
// NOTE: this flag is currently unused. A useful remnant of an old throttling algorithm.
bool mThrottleResponse;
// state flags, all logically boolean, but not packed together into a
@ -377,8 +378,8 @@ public:
// but later can be dispatched via spdy (not subject to rate pacing).
void CancelPacing(nsresult reason);
// Forwards to the connection's ThrottleResponse. If there is no connection
// at the time, we set a flag to do it on connection assignment.
// Called only on the socket thread. Updates the flag whether the transaction
// should make the underlying connection or session stop reading from the socket.
void ThrottleResponse(bool aThrottle);
private: