Bug 1365306 - Remove net::ThrottlingService, don't suspend/resume download channels on page load. r=hurley
authorHonza Bambas <honzab.moz@firemni.cz>
Thu, 18 May 2017 14:09:00 -0400
changeset 360521 e4d329c85dfba110181afbc1586ac239470b9608
parent 360520 541bf10775c707290af037b19da27c41dff4c738
child 360522 4b9458e5d250b540c23de2fd3c72aae968e1cd74
push id31884
push userryanvm@gmail.com
push dateThu, 25 May 2017 00:45:30 +0000
treeherdermozilla-central@f81bcc23d37d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershurley
bugs1365306
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1365306 - Remove net::ThrottlingService, don't suspend/resume download channels on page load. r=hurley
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
netwerk/base/ThrottlingService.cpp
netwerk/base/ThrottlingService.h
netwerk/base/moz.build
netwerk/base/nsIThrottlingService.idl
netwerk/build/nsNetCID.h
netwerk/build/nsNetModule.cpp
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/ipc/PNecko.ipdl
netwerk/protocol/http/Http2Session.cpp
netwerk/protocol/http/Http2Session.h
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/nsAHttpConnection.h
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnection.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -7604,20 +7604,16 @@ nsDocShell::OnSecurityChange(nsIWebProgr
   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
   return NS_OK;
 }
 
 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;
   }
 
   nsCOMPtr<nsIConsoleReportCollector> reporter = do_QueryInterface(aChannel);
   if (reporter) {
     nsCOMPtr<nsILoadGroup> loadGroup;
     aChannel->GetLoadGroup(getter_AddRefs(loadGroup));
@@ -10794,26 +10790,16 @@ nsDocShell::InternalLoad(nsIURI* aURI,
   OriginAttributes attrs = GetOriginAttributes();
   attrs.SetFirstPartyDomain(isTopLevelDoc, aURI);
 
   net::PredictorLearn(aURI, nullptr,
                       nsINetworkPredictor::LEARN_LOAD_TOPLEVEL, attrs);
   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),
                  aReferrerPolicy,
                  aTriggeringPrincipal, principalToInherit, aTypeHint,
                  aFileName, aPostData, aHeadersData,
                  aFirstParty, aDocShell, getter_AddRefs(req),
                  (aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -55,17 +55,16 @@
 #include "nsILinkHandler.h"
 #include "nsIClipboardCommands.h"
 #include "nsITabParent.h"
 #include "nsCRT.h"
 #include "prtime.h"
 #include "nsRect.h"
 #include "Units.h"
 #include "nsIDeprecationWarner.h"
-#include "nsIThrottlingService.h"
 
 namespace mozilla {
 enum class TaskCategory;
 namespace dom {
 class EventTarget;
 class PendingGlobalHistoryEntry;
 typedef uint32_t ScreenOrientationInternal;
 } // namespace dom
@@ -1096,14 +1095,11 @@ public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIINTERFACEREQUESTOR
 
   protected:
     virtual ~InterfaceRequestorProxy();
     InterfaceRequestorProxy() {}
     nsWeakPtr mWeakPtr;
   };
-
-private:
-  mozilla::UniquePtr<mozilla::net::Throttler> mThrottler;
 };
 
 #endif /* nsDocShell_h__ */
deleted file mode 100644
--- a/netwerk/base/ThrottlingService.cpp
+++ /dev/null
@@ -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;
-  }
-}
-
-}
-}
deleted file mode 100644
--- a/netwerk/base/ThrottlingService.h
+++ /dev/null
@@ -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
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -112,17 +112,16 @@ XPIDL_SOURCES += [
     'nsIStreamListenerTee.idl',
     'nsIStreamLoader.idl',
     'nsIStreamTransportService.idl',
     'nsISyncStreamListener.idl',
     'nsISystemProxySettings.idl',
     'nsIThreadRetargetableRequest.idl',
     'nsIThreadRetargetableStreamListener.idl',
     'nsIThrottledInputChannel.idl',
-    'nsIThrottlingService.idl',
     'nsITimedChannel.idl',
     'nsITLSServerSocket.idl',
     'nsITraceableChannel.idl',
     'nsITransport.idl',
     'nsIUDPSocket.idl',
     'nsIUnicharStreamLoader.idl',
     'nsIUploadChannel.idl',
     'nsIUploadChannel2.idl',
@@ -245,17 +244,16 @@ UNIFIED_SOURCES += [
     'ProxyAutoConfig.cpp',
     'RedirectChannelRegistrar.cpp',
     'RequestContextService.cpp',
     'SimpleBuffer.cpp',
     'SimpleChannel.cpp',
     'StreamingProtocolService.cpp',
     'TCPFastOpenLayer.cpp',
     'ThrottleQueue.cpp',
-    'ThrottlingService.cpp',
     'Tickler.cpp',
     'TLSServerSocket.cpp',
 ]
 
 if CONFIG['MOZ_RUST_URLPARSE']:
     EXPORTS.mozilla.net += [ 'RustURL.h' ]
     UNIFIED_SOURCES += [ 'RustURL.cpp' ]
 
deleted file mode 100644
--- a/netwerk/base/nsIThrottlingService.idl
+++ /dev/null
@@ -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
-%}
--- a/netwerk/build/nsNetCID.h
+++ b/netwerk/build/nsNetCID.h
@@ -489,27 +489,16 @@
 #define NS_REQUESTCONTEXTSERVICE_CID \
 { /* d5499fa7-7ba8-49ff-9e30-1858b99ace69 */ \
     0xd5499fa7, \
     0x7ba8, \
     0x49ff, \
     {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
  */
 
 // service implementing nsICacheService.
 #define NS_CACHESERVICE_CONTRACTID \
     "@mozilla.org/network/cache-service;1"
 #define NS_CACHESERVICE_CID                          \
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -33,17 +33,16 @@
 #include "nsApplicationCacheService.h"
 #include "nsMimeTypes.h"
 #include "nsDNSPrefetch.h"
 #include "nsAboutProtocolHandler.h"
 #include "nsXULAppAPI.h"
 #include "nsCategoryCache.h"
 #include "nsIContentSniffer.h"
 #include "Predictor.h"
-#include "ThrottlingService.h"
 #include "nsIThreadPool.h"
 #include "mozilla/net/NeckoChild.h"
 
 #include "nsNetCID.h"
 
 #ifndef XP_MACOSX
 #define BUILD_BINHEX_DECODER 1
 #endif
@@ -870,17 +869,16 @@ NS_DEFINE_NAMED_CID(NS_REDIRECTCHANNELRE
 NS_DEFINE_NAMED_CID(NS_CACHE_STORAGE_SERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_NSILOADCONTEXTINFOFACTORY_CID);
 NS_DEFINE_NAMED_CID(NS_NETWORKPREDICTOR_CID);
 NS_DEFINE_NAMED_CID(NS_CAPTIVEPORTAL_CID);
 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 },
     { &kNS_STREAMTRANSPORTSERVICE_CID, false, nullptr, nsStreamTransportServiceConstructor },
     { &kNS_SOCKETTRANSPORTSERVICE_CID, false, nullptr, nsSocketTransportServiceConstructor },
     { &kNS_SERVERSOCKET_CID, false, nullptr, nsServerSocketConstructor },
     { &kNS_TLSSERVERSOCKET_CID, false, nullptr, TLSServerSocketConstructor },
     { &kNS_UDPSOCKET_CID, false, nullptr, nsUDPSocketConstructor },
@@ -1024,17 +1022,16 @@ static const mozilla::Module::CIDEntry k
     { &kNS_CACHE_STORAGE_SERVICE_CID, false, nullptr, CacheStorageServiceConstructor },
     { &kNS_NSILOADCONTEXTINFOFACTORY_CID, false, nullptr, LoadContextInfoFactoryConstructor },
     { &kNS_NETWORKPREDICTOR_CID, false, nullptr, mozilla::net::Predictor::Create },
     { &kNS_CAPTIVEPORTAL_CID, false, nullptr, mozilla::net::CaptivePortalServiceConstructor },
     { &kNS_REQUESTCONTEXTSERVICE_CID, false, nullptr, RequestContextServiceConstructor },
 #ifdef BUILD_NETWORK_INFO_SERVICE
     { &kNETWORKINFOSERVICE_CID, false, nullptr, nsNetworkInfoServiceConstructor },
 #endif
-    { &kNS_THROTTLINGSERVICE_CID, false, nullptr, mozilla::net::ThrottlingService::Create },
     { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
     { NS_IOSERVICE_CONTRACTID, &kNS_IOSERVICE_CID },
     { NS_NETUTIL_CONTRACTID, &kNS_IOSERVICE_CID },
     { NS_STREAMTRANSPORTSERVICE_CONTRACTID, &kNS_STREAMTRANSPORTSERVICE_CID },
     { NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &kNS_SOCKETTRANSPORTSERVICE_CID },
@@ -1183,17 +1180,16 @@ static const mozilla::Module::ContractID
     { NS_CACHE_STORAGE_SERVICE_CONTRACTID2, &kNS_CACHE_STORAGE_SERVICE_CID },
     { NS_NSILOADCONTEXTINFOFACTORY_CONTRACTID, &kNS_NSILOADCONTEXTINFOFACTORY_CID },
     { NS_NETWORKPREDICTOR_CONTRACTID, &kNS_NETWORKPREDICTOR_CID },
     { NS_CAPTIVEPORTAL_CONTRACTID, &kNS_CAPTIVEPORTAL_CID },
     { NS_REQUESTCONTEXTSERVICE_CONTRACTID, &kNS_REQUESTCONTEXTSERVICE_CID },
 #ifdef BUILD_NETWORK_INFO_SERVICE
     { NETWORKINFOSERVICE_CONTRACT_ID, &kNETWORKINFOSERVICE_CID },
 #endif
-    { NS_THROTTLINGSERVICE_CONTRACTID, &kNS_THROTTLINGSERVICE_CID },
     { nullptr }
 };
 
 static const mozilla::Module kNeckoModule = {
     mozilla::Module::kVersion,
     kNeckoCIDs,
     kNeckoContracts,
     kNeckoCategories,
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -43,17 +43,16 @@
 #include "nsEscape.h"
 #include "SerializedLoadContext.h"
 #include "nsAuthInformationHolder.h"
 #include "nsIAuthPromptCallback.h"
 #include "ContentPrincipal.h"
 #include "nsINetworkPredictor.h"
 #include "nsINetworkPredictorVerifier.h"
 #include "nsISpeculativeConnect.h"
-#include "nsIThrottlingService.h"
 #include "nsNetUtil.h"
 
 using mozilla::OriginAttributes;
 using mozilla::dom::ChromeUtils;
 using mozilla::dom::ContentParent;
 using mozilla::dom::TabContext;
 using mozilla::dom::TabParent;
 using mozilla::net::PTCPSocketParent;
@@ -942,33 +941,16 @@ NeckoParent::RecvRemoveRequestContext(co
   }
 
   rcsvc->RemoveRequestContext(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)
 {
   if (NS_FAILED(NS_NotifyCurrentTopLevelOuterContentWindowId(aWindowId))) {
     NS_WARNING("NS_NotifyCurrentTopLevelOuterContentWindowId failed!");
   }
 
   return IPC_OK();
 }
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -5,17 +5,16 @@
  * 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 "mozilla/BasePrincipal.h"
 #include "mozilla/net/PNeckoParent.h"
 #include "mozilla/net/NeckoCommon.h"
 #include "nsIAuthPrompt2.h"
 #include "nsINetworkPredictor.h"
-#include "nsIThrottlingService.h"
 #include "nsNetUtil.h"
 
 #ifndef mozilla_net_NeckoParent_h
 #define mozilla_net_NeckoParent_h
 
 namespace mozilla {
 namespace net {
 
@@ -231,22 +230,15 @@ protected:
   virtual mozilla::ipc::IPCResult RecvPredLearn(const ipc::URIParams& aTargetURI,
                                                 const ipc::OptionalURIParams& aSourceURI,
                                                 const PredictorPredictReason& aReason,
                                                 const OriginAttributes& aOriginAttributes) override;
   virtual mozilla::ipc::IPCResult RecvPredReset() override;
 
   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
 } // namespace mozilla
 
 #endif // mozilla_net_NeckoParent_h
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -120,22 +120,16 @@ parent:
   async OnAuthCancelled(uint64_t callbackId, bool userCancel);
 
   async RemoveRequestContext(uint64_t rcid);
 
   async PAltDataOutputStream(nsCString type, PHttpChannel channel);
 
   async PStunAddrsRequest();
 
-  /**
-   * Throttling of channels
-   */
-  async IncreaseThrottlePressure();
-  async DecreaseThrottlePressure();
-
   prio(high) async NotifyCurrentTopLevelOuterContentWindowId(uint64_t windowId);
 
 child:
   /*
    * Bring up the http auth prompt for a nested remote mozbrowser.
    * NestedFrameId is the id corresponding to the PBrowser.  It is the same id
    * that was passed to the PBrowserOrId param in to the PHttpChannel constructor
    */
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -4243,16 +4243,10 @@ Http2Session::RealJoinConnection(const n
     key2.AppendInt(port);
     if (!mJoinConnectionCache.Get(key2)) {
       mJoinConnectionCache.Put(key2, joinedReturn);
     }
   }
   return joinedReturn;
 }
 
-void
-Http2Session::ThrottleResponse(bool aThrottle)
-{
-  // Response throttling on an h2 connection will be implemented later.
-}
-
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/Http2Session.h
+++ b/netwerk/protocol/http/Http2Session.h
@@ -47,17 +47,16 @@ public:
 
   MOZ_MUST_USE bool AddStream(nsAHttpTransaction *, int32_t,
                               bool, nsIInterfaceRequestor *) override;
   bool CanReuse() override { return !mShouldGoAway && !mClosed; }
   bool RoomForMoreStreams() override;
   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
   // have this invoked. It might happen sooner depending on the needs of
   // other connections.
   uint32_t  ReadTimeoutTick(PRIntervalTime now) override;
 
   // Idle time represents time since "goodput".. e.g. a data or header frame
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -57,17 +57,16 @@
 #include "mozilla/BinarySearch.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Move.h"
 #include "nsIHttpHeaderVisitor.h"
 #include "nsIMIMEInputStream.h"
 #include "nsIXULRuntime.h"
 #include "nsICacheInfoChannel.h"
 #include "nsIDOMWindowUtils.h"
-#include "nsIThrottlingService.h"
 
 #include <algorithm>
 #include "HttpBaseChannel.h"
 
 namespace mozilla {
 namespace net {
 
 static
@@ -3066,23 +3065,16 @@ HttpBaseChannel::SetNewListener(nsIStrea
 // HttpBaseChannel helpers
 //-----------------------------------------------------------------------------
 
 void
 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;
   mProgressSink = nullptr;
   mCompressListener = nullptr;
 }
 
 void
--- a/netwerk/protocol/http/nsAHttpConnection.h
+++ b/netwerk/protocol/http/nsAHttpConnection.h
@@ -141,24 +141,16 @@ public:
     virtual int64_t BytesWritten() = 0;
 
     // Update the callbacks used to provide security info. May be called on
     // any thread.
     virtual void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks) = 0;
 
     // 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)
 
 #define NS_DECL_NSAHTTPCONNECTION(fwdObject)                    \
     MOZ_MUST_USE nsresult OnHeadersAvailable(nsAHttpTransaction *,  \
                                              nsHttpRequestHead *,   \
                                              nsHttpResponseHead *,  \
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -102,17 +102,16 @@
 #include "nsISocketProvider.h"
 #include "mozilla/net/Predictor.h"
 #include "mozilla/MathAlgorithms.h"
 #include "CacheControlParser.h"
 #include "nsMixedContentBlocker.h"
 #include "HSTSPrimerListener.h"
 #include "CacheStorageService.h"
 #include "HttpChannelParent.h"
-#include "nsIThrottlingService.h"
 #include "nsIBufferedStreams.h"
 #include "nsIFileStreams.h"
 #include "nsIMIMEInputStream.h"
 #include "nsIMultiplexInputStream.h"
 
 #ifdef MOZ_TASK_TRACER
 #include "GeckoTaskTracer.h"
 #endif
@@ -706,17 +705,17 @@ nsHttpChannel::ContinueConnect()
 
     rv = mTransactionPump->AsyncRead(this, nullptr);
     if (NS_FAILED(rv)) return rv;
 
     uint32_t suspendCount = mSuspendCount;
     while (suspendCount--)
         mTransactionPump->Suspend();
 
-    if (mSuspendCount && mClassOfService & nsIClassOfService::Throttleable) {
+    if (mClassOfService & nsIClassOfService::Throttleable) {
         gHttpHandler->ThrottleTransaction(mTransaction, true);
     }
 
     return NS_OK;
 }
 
 void
 nsHttpChannel::SpeculativeConnect()
@@ -6622,28 +6621,19 @@ nsHttpChannel::ContinueBeginConnect()
 // HttpChannel::nsIClassOfService
 //-----------------------------------------------------------------------------
 
 void
 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
 nsHttpChannel::SetClassFlags(uint32_t inFlags)
 {
     uint32_t previous = mClassOfService;
     mClassOfService = inFlags;
     if (previous != mClassOfService) {
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -81,18 +81,16 @@ nsHttpConnection::nsHttpConnection()
     , mResponseTimeoutEnabled(false)
     , mTCPKeepaliveConfig(kTCPKeepaliveDisabled)
     , mForceSendPending(false)
     , m0RTTChecked(false)
     , mWaitingFor0RTTResponse(false)
     , mContentBytesWritten0RTT(0)
     , mEarlyDataNegotiated(false)
     , mDid0RTTSpdy(false)
-    , mResponseThrottled(false)
-    , mResumeRecvOnUnthrottle(false)
     , mFastOpen(false)
     , mFastOpenStatus(TFO_NOT_TRIED)
     , mForceSendDuringFastOpenPending(false)
     , mReceivedSocketWouldBlockDuringFastOpen(false)
 {
     LOG(("Creating nsHttpConnection @%p\n", this));
 
     // the default timeout is for when this connection has not yet processed a
@@ -1466,32 +1464,16 @@ nsHttpConnection::ResumeRecv()
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
     if (mFastOpen) {
         LOG(("nsHttpConnection::ResumeRecv - do not waiting for read during "
              "fast open! [this=%p]\n", this));
         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
     // with actual read data in OnSocketReadable() we are only measuring
     // the latency between those two acts and not all the processing that
     // may get done before the ResumeRecv() call
     mLastReadTime = PR_IntervalNow();
 
@@ -2160,42 +2142,16 @@ nsHttpConnection::DisableTCPKeepalives()
     }
     if (mTCPKeepaliveTransitionTimer) {
         mTCPKeepaliveTransitionTimer->Cancel();
         mTCPKeepaliveTransitionTimer = nullptr;
     }
     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
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ADDREF(nsHttpConnection)
 NS_IMPL_RELEASE(nsHttpConnection)
 
 NS_INTERFACE_MAP_BEGIN(nsHttpConnection)
--- a/netwerk/protocol/http/nsHttpConnection.h
+++ b/netwerk/protocol/http/nsHttpConnection.h
@@ -226,18 +226,16 @@ public:
             (mTrafficCount == (mTotalBytesWritten + mTotalBytesRead));
     }
     // override of nsAHttpConnection
     virtual uint32_t Version();
 
     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;
     }
 
 private:
     // Value (set in mTCPKeepaliveConfig) indicates which set of prefs to use.
     enum TCPKeepaliveConfig {
       kTCPKeepaliveDisabled = 0,
@@ -391,23 +389,16 @@ private:
                                                              // are waiting
                                                              // for the end of
                                                              // the handsake.
     int64_t                        mContentBytesWritten0RTT;
     bool                           mEarlyDataNegotiated; //Only used for telemetry
     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;
 
     bool                           mForceSendDuringFastOpenPending;
     bool                           mReceivedSocketWouldBlockDuringFastOpen;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsHttpConnection, NS_HTTPCONNECTION_IID)
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -1635,38 +1635,30 @@ nsHttpConnectionMgr::DispatchTransaction
 // need for consumer code to know when to give the connection back to the
 // connection manager.
 //
 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; }
 private:
     virtual ~ConnectionHandle();
     RefPtr<nsHttpConnection> mConn;
 };
 
 nsAHttpConnection *
 nsHttpConnectionMgr::MakeConnectionHandle(nsHttpConnection *aWrapped)
 {
     return new ConnectionHandle(aWrapped);
 }
 
-void ConnectionHandle::ThrottleResponse(bool aThrottle)
-{
-    if (mConn) {
-        mConn->ThrottleResponse(aThrottle);
-    }
-}
-
 ConnectionHandle::~ConnectionHandle()
 {
     if (mConn) {
         nsresult rv = gHttpHandler->ReclaimConnection(mConn);
         if (NS_FAILED(rv)) {
             LOG(("ConnectionHandle::~ConnectionHandle\n"
                  "    failed to reclaim connection\n"));
         }
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -48,17 +48,16 @@
 #include "nsIParentalControlsService.h"
 #include "nsPIDOMWindow.h"
 #include "nsINetworkLinkService.h"
 #include "nsHttpChannelAuthProvider.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsSocketTransportService2.h"
 #include "nsIOService.h"
-#include "nsIThrottlingService.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIXULRuntime.h"
 #include "nsCharSeparatedTokenizer.h"
 
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/net/NeckoParent.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/Telemetry.h"
@@ -710,27 +709,16 @@ nsresult
 nsHttpHandler::GetIOService(nsIIOService** result)
 {
     NS_ENSURE_ARG_POINTER(result);
 
     NS_ADDREF(*result = mIOService);
     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()
 {
     // only confirm rand seeding on socket thread
     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
     // rand() provides different amounts of PRNG on different platforms.
     // 15 or 31 bits are common amounts.
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -22,17 +22,16 @@
 class nsIHttpChannel;
 class nsIPrefBranch;
 class nsICancelable;
 class nsICookieService;
 class nsIIOService;
 class nsIRequestContextService;
 class nsISiteSecurityService;
 class nsIStreamConverterService;
-class nsIThrottlingService;
 
 
 namespace mozilla {
 namespace net {
 
 bool OnSocketThread();
 
 class ATokenBucketEvent;
@@ -291,17 +290,16 @@ public:
     //
     // The HTTP handler caches pointers to specific XPCOM services, and
     // provides the following helper routines for accessing those services:
     //
     MOZ_MUST_USE nsresult GetStreamConverterService(nsIStreamConverterService **);
     MOZ_MUST_USE nsresult GetIOService(nsIIOService** service);
     nsICookieService * GetCookieService(); // not addrefed
     nsISiteSecurityService * GetSSService();
-    nsIThrottlingService * GetThrottlingService();
 
     // callable from socket thread only
     uint32_t Get32BitsOfPseudoRandom();
 
     // Called by the channel synchronously during asyncOpen
     void OnOpeningRequest(nsIHttpChannel *chan)
     {
         NotifyObservers(chan, NS_HTTP_ON_OPENING_REQUEST_TOPIC);
@@ -407,17 +405,16 @@ private:
     void EnsureUAOverridesInit();
 private:
 
     // cached services
     nsMainThreadPtrHandle<nsIIOService>              mIOService;
     nsMainThreadPtrHandle<nsIStreamConverterService> mStreamConvSvc;
     nsMainThreadPtrHandle<nsICookieService>          mCookieService;
     nsMainThreadPtrHandle<nsISiteSecurityService>    mSSService;
-    nsMainThreadPtrHandle<nsIThrottlingService>      mThrottlingService;
 
     // the authentication credentials cache
     nsHttpAuthCache mAuthCache;
     nsHttpAuthCache mPrivateAuthCache;
 
     // the connection manager
     RefPtr<nsHttpConnectionMgr> mConnMgr;
 
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -154,22 +154,17 @@ nsHttpTransaction::nsHttpTransaction()
     mSelfAddr.raw.family = PR_AF_UNSPEC;
     mPeerAddr.raw.family = PR_AF_UNSPEC;
 }
 
 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()
 {
     LOG(("Destroying nsHttpTransaction @%p\n", this));
     if (mTransactionObserver) {
         mTransactionObserver->Complete(this, NS_OK);
     }
@@ -474,20 +469,16 @@ nsHttpTransaction::TakeSubTransactions(
 
 void
 nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
 {
     {
         MutexAutoLock lock(mLock);
         mConnection = conn;
     }
-
-    if (conn && mThrottleResponse) {
-        gHttpHandler->ThrottleTransaction(this, true);
-    }
 }
 
 void
 nsHttpTransaction::GetSecurityCallbacks(nsIInterfaceRequestor **cb)
 {
     MutexAutoLock lock(mLock);
     nsCOMPtr<nsIInterfaceRequestor> tmp(mCallbacks);
     tmp.forget(cb);
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -308,16 +308,17 @@ private:
     // access to it from the networking thread may happen either before or
     // after the main thread modifies it. To deal with raciness, only unsetting
     // bitfields should be allowed: 'lost races' will thus err on the
     // conservative side, e.g. by going ahead with a 2nd DNS refresh.
     Atomic<uint32_t>                mCapsToClear;
     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
     // bitfield so as to avoid bitfield-induced races.  See bug 560579.
     bool                            mClosed;
     bool                            mConnected;
     bool                            mHaveStatusLine;
     bool                            mHaveAllHeaders;
@@ -372,18 +373,18 @@ public:
     void OnTokenBucketAdmitted() override; // ATokenBucketEvent
 
     // CancelPacing() can be used to tell the token bucket to remove this
     // transaction from the list of pending transactions. This is used when a
     // transaction is believed to be HTTP/1 (and thus subject to rate pacing)
     // 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:
     bool mSubmittedRatePacing;
     bool mPassedRatePacing;
     bool mSynchronousRatePaceRequest;
     nsCOMPtr<nsICancelable> mTokenBucketCancel;
 public: