Bug 1478101 - Split AbortSignal in 2 classes: AbortSignal and AbortSignalImpl, r=bz
authorAndrea Marchesini <amarchesini@mozilla.com>
Sun, 26 Aug 2018 14:16:21 +0200
changeset 488542 2d0ebe0ace0b3086f03c39e1d959b1ee92165c3b
parent 488541 291b098c977eefa575929c76febffd440488e511
child 488543 b2d0cb1ce26f5f3f19a7bd65c74ebf82c6e7d53e
push id9730
push usercsabou@mozilla.com
push dateMon, 27 Aug 2018 16:38:33 +0000
treeherdermozilla-beta@4084eef2130f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1478101
milestone63.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 1478101 - Split AbortSignal in 2 classes: AbortSignal and AbortSignalImpl, r=bz
dom/abort/AbortSignal.cpp
dom/abort/AbortSignal.h
dom/fetch/Fetch.cpp
dom/fetch/Fetch.h
dom/fetch/FetchConsumer.cpp
dom/fetch/FetchConsumer.h
dom/fetch/FetchDriver.cpp
dom/fetch/FetchDriver.h
dom/fetch/FetchObserver.cpp
dom/fetch/FetchObserver.h
dom/fetch/Request.cpp
dom/fetch/Request.h
dom/fetch/Response.cpp
dom/fetch/Response.h
--- a/dom/abort/AbortSignal.cpp
+++ b/dom/abort/AbortSignal.cpp
@@ -7,102 +7,119 @@
 #include "AbortSignal.h"
 
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/AbortSignalBinding.h"
 
 namespace mozilla {
 namespace dom {
 
+// AbortSignalImpl
+// ----------------------------------------------------------------------------
+
+AbortSignalImpl::AbortSignalImpl(bool aAborted)
+  : mAborted(aAborted)
+{}
+
+bool
+AbortSignalImpl::Aborted() const
+{
+  return mAborted;
+}
+
+void
+AbortSignalImpl::Abort()
+{
+  if (mAborted) {
+    return;
+  }
+
+  mAborted = true;
+
+  // Let's inform the followers.
+  for (AbortFollower* follower : mFollowers) {
+    follower->Abort();
+  }
+}
+
+void
+AbortSignalImpl::AddFollower(AbortFollower* aFollower)
+{
+  MOZ_DIAGNOSTIC_ASSERT(aFollower);
+  if (!mFollowers.Contains(aFollower)) {
+    mFollowers.AppendElement(aFollower);
+  }
+}
+
+void
+AbortSignalImpl::RemoveFollower(AbortFollower* aFollower)
+{
+  MOZ_DIAGNOSTIC_ASSERT(aFollower);
+  mFollowers.RemoveElement(aFollower);
+}
+
+// AbortSignal
+// ----------------------------------------------------------------------------
+
 NS_IMPL_CYCLE_COLLECTION_CLASS(AbortSignal)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AbortSignal,
                                                   DOMEventTargetHelper)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFollowingSignal)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(AbortSignal,
                                                 DOMEventTargetHelper)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mFollowingSignal)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AbortSignal)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(AbortSignal, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(AbortSignal, DOMEventTargetHelper)
 
 AbortSignal::AbortSignal(nsIGlobalObject* aGlobalObject,
                          bool aAborted)
   : DOMEventTargetHelper(aGlobalObject)
-  , mAborted(aAborted)
-{}
-
-AbortSignal::AbortSignal(bool aAborted)
-  : mAborted(aAborted)
+  , AbortSignalImpl(aAborted)
 {}
 
 JSObject*
 AbortSignal::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return AbortSignal_Binding::Wrap(aCx, this, aGivenProto);
 }
 
-bool
-AbortSignal::Aborted() const
-{
-  return mAborted;
-}
-
 void
 AbortSignal::Abort()
 {
-  MOZ_ASSERT(!mAborted);
-  mAborted = true;
-
-  // Let's inform the followers.
-  for (uint32_t i = 0; i < mFollowers.Length(); ++i) {
-    mFollowers[i]->Abort();
-  }
+  AbortSignalImpl::Abort();
 
   EventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
 
   RefPtr<Event> event =
     Event::Constructor(this, NS_LITERAL_STRING("abort"), init);
   event->SetTrusted(true);
 
   DispatchEvent(*event);
 }
 
-void
-AbortSignal::AddFollower(AbortFollower* aFollower)
-{
-  MOZ_DIAGNOSTIC_ASSERT(aFollower);
-  if (!mFollowers.Contains(aFollower)) {
-    mFollowers.AppendElement(aFollower);
-  }
-}
-
-void
-AbortSignal::RemoveFollower(AbortFollower* aFollower)
-{
-  MOZ_DIAGNOSTIC_ASSERT(aFollower);
-  mFollowers.RemoveElement(aFollower);
-}
-
 // AbortFollower
 // ----------------------------------------------------------------------------
 
 AbortFollower::~AbortFollower()
 {
   Unfollow();
 }
 
 void
-AbortFollower::Follow(AbortSignal* aSignal)
+AbortFollower::Follow(AbortSignalImpl* aSignal)
 {
   MOZ_DIAGNOSTIC_ASSERT(aSignal);
 
   Unfollow();
 
   mFollowingSignal = aSignal;
   aSignal->AddFollower(this);
 }
--- a/dom/abort/AbortSignal.h
+++ b/dom/abort/AbortSignal.h
@@ -8,70 +8,87 @@
 #define mozilla_dom_AbortSignal_h
 
 #include "mozilla/DOMEventTargetHelper.h"
 
 namespace mozilla {
 namespace dom {
 
 class AbortSignal;
+class AbortSignalImpl;
 
-// This class must be implemented by objects who want to follow a AbortSignal.
+// This class must be implemented by objects who want to follow a
+// AbortSignalImpl.
 class AbortFollower
 {
 public:
   virtual void Abort() = 0;
 
   void
-  Follow(AbortSignal* aSignal);
+  Follow(AbortSignalImpl* aSignal);
 
   void
   Unfollow();
 
   bool
   IsFollowing() const;
 
 protected:
   virtual ~AbortFollower();
 
-  RefPtr<AbortSignal> mFollowingSignal;
+  // Subclasses of AbortFollower must Traverse/Unlink this member.
+  RefPtr<AbortSignalImpl> mFollowingSignal;
 };
 
-class AbortSignal final : public DOMEventTargetHelper
-                        , public AbortFollower
+// Any subclass of this class must Traverse/Unlink mFollowingSignal.
+class AbortSignalImpl : public AbortFollower
+                      , public nsISupports
 {
 public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AbortSignal, DOMEventTargetHelper)
-
-  AbortSignal(nsIGlobalObject* aGlobalObject, bool aAborted);
-  explicit AbortSignal(bool aAborted);
-
-  JSObject*
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+  explicit AbortSignalImpl(bool aAborted);
 
   bool
   Aborted() const;
 
   void
   Abort() override;
 
-  IMPL_EVENT_HANDLER(abort);
-
   void
   AddFollower(AbortFollower* aFollower);
 
   void
   RemoveFollower(AbortFollower* aFollower);
 
+protected:
+  virtual ~AbortSignalImpl() = default;
+
 private:
-  ~AbortSignal() = default;
-
   // Raw pointers. AbortFollower unregisters itself in the DTOR.
   nsTArray<AbortFollower*> mFollowers;
 
   bool mAborted;
 };
 
+class AbortSignal final : public DOMEventTargetHelper
+                        , public AbortSignalImpl
+{
+public:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AbortSignal, DOMEventTargetHelper)
+
+  AbortSignal(nsIGlobalObject* aGlobalObject, bool aAborted);
+
+  JSObject*
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+
+  IMPL_EVENT_HANDLER(abort);
+
+  void
+  Abort() override;
+
+private:
+  ~AbortSignal() = default;
+};
+
 } // dom namespace
 } // mozilla namespace
 
 #endif // mozilla_dom_AbortSignal_h
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -69,98 +69,123 @@ AbortStream(JSContext* aCx, JS::Handle<J
     return;
   }
 
   JS::ReadableStreamError(aCx, aStream, value);
 }
 
 } // anonymous
 
-// This class helps the proxying of AbortSignal changes cross threads.
+class AbortSignalMainThread final : public AbortSignalImpl
+{
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS(AbortSignalMainThread)
+
+  explicit AbortSignalMainThread(bool aAborted)
+    : AbortSignalImpl(aAborted)
+  {}
+
+private:
+  ~AbortSignalMainThread() = default;
+};
+
+NS_IMPL_CYCLE_COLLECTION(AbortSignalMainThread, mFollowingSignal)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AbortSignalMainThread)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(AbortSignalMainThread)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(AbortSignalMainThread)
+
+// This class helps the proxying of AbortSignalImpl changes cross threads.
 class AbortSignalProxy final : public AbortFollower
 {
   // This is created and released on the main-thread.
-  RefPtr<AbortSignal> mSignalMainThread;
+  RefPtr<AbortSignalImpl> mSignalImplMainThread;
 
   // The main-thread event target for runnable dispatching.
   nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
 
-  // This value is used only for the creation of AbortSignal on the
+  // This value is used only for the creation of AbortSignalImpl on the
   // main-thread. They are not updated.
   const bool mAborted;
 
-  // This runnable propagates changes from the AbortSignal on workers to the
-  // AbortSignal on main-thread.
+  // This runnable propagates changes from the AbortSignalImpl on workers to the
+  // AbortSignalImpl on main-thread.
   class AbortSignalProxyRunnable final : public Runnable
   {
     RefPtr<AbortSignalProxy> mProxy;
 
   public:
     explicit AbortSignalProxyRunnable(AbortSignalProxy* aProxy)
       : Runnable("dom::AbortSignalProxy::AbortSignalProxyRunnable")
       , mProxy(aProxy)
     {}
 
     NS_IMETHOD
     Run() override
     {
       MOZ_ASSERT(NS_IsMainThread());
-      AbortSignal* signal = mProxy->GetOrCreateSignalForMainThread();
-      signal->Abort();
+      AbortSignalImpl* signalImpl =
+        mProxy->GetOrCreateSignalImplForMainThread();
+      signalImpl->Abort();
       return NS_OK;
     }
   };
 
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbortSignalProxy)
 
-  AbortSignalProxy(AbortSignal* aSignal, nsIEventTarget* aMainThreadEventTarget)
+  AbortSignalProxy(AbortSignalImpl* aSignalImpl,
+                   nsIEventTarget* aMainThreadEventTarget)
     : mMainThreadEventTarget(aMainThreadEventTarget)
-    , mAborted(aSignal->Aborted())
+    , mAborted(aSignalImpl->Aborted())
   {
     MOZ_ASSERT(mMainThreadEventTarget);
-    Follow(aSignal);
+    Follow(aSignalImpl);
   }
 
   void
   Abort() override
   {
     RefPtr<AbortSignalProxyRunnable> runnable =
       new AbortSignalProxyRunnable(this);
     mMainThreadEventTarget->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL);
   }
 
-  AbortSignal*
-  GetOrCreateSignalForMainThread()
+  AbortSignalImpl*
+  GetOrCreateSignalImplForMainThread()
   {
     MOZ_ASSERT(NS_IsMainThread());
-    if (!mSignalMainThread) {
-      mSignalMainThread = new AbortSignal(mAborted);
+    if (!mSignalImplMainThread) {
+      mSignalImplMainThread = new AbortSignalMainThread(mAborted);
     }
-    return mSignalMainThread;
+    return mSignalImplMainThread;
   }
 
-  AbortSignal*
-  GetSignalForTargetThread()
+  AbortSignalImpl*
+  GetSignalImplForTargetThread()
   {
     return mFollowingSignal;
   }
 
   void
   Shutdown()
   {
     Unfollow();
   }
 
 private:
   ~AbortSignalProxy()
   {
     NS_ProxyRelease(
-      "AbortSignalProxy::mSignalMainThread",
-      mMainThreadEventTarget, mSignalMainThread.forget());
+      "AbortSignalProxy::mSignalImplMainThread",
+      mMainThreadEventTarget, mSignalImplMainThread.forget());
   }
 };
 
 class WorkerFetchResolver final : public FetchDriverObserver
 {
   // Thread-safe:
   RefPtr<PromiseWorkerProxy> mPromiseProxy;
   RefPtr<AbortSignalProxy> mSignalProxy;
@@ -168,30 +193,31 @@ class WorkerFetchResolver final : public
   // Touched only on the worker thread.
   RefPtr<FetchObserver> mFetchObserver;
   RefPtr<WeakWorkerRef> mWorkerRef;
 
 public:
   // Returns null if worker is shutting down.
   static already_AddRefed<WorkerFetchResolver>
   Create(WorkerPrivate* aWorkerPrivate, Promise* aPromise,
-         AbortSignal* aSignal, FetchObserver* aObserver)
+         AbortSignalImpl* aSignalImpl, FetchObserver* aObserver)
   {
     MOZ_ASSERT(aWorkerPrivate);
     aWorkerPrivate->AssertIsOnWorkerThread();
     RefPtr<PromiseWorkerProxy> proxy =
       PromiseWorkerProxy::Create(aWorkerPrivate, aPromise);
     if (!proxy) {
       return nullptr;
     }
 
     RefPtr<AbortSignalProxy> signalProxy;
-    if (aSignal) {
+    if (aSignalImpl) {
       signalProxy =
-        new AbortSignalProxy(aSignal, aWorkerPrivate->MainThreadEventTarget());
+        new AbortSignalProxy(aSignalImpl,
+                             aWorkerPrivate->MainThreadEventTarget());
     }
 
     RefPtr<WorkerFetchResolver> r =
       new WorkerFetchResolver(proxy, signalProxy, aObserver);
 
     RefPtr<WeakWorkerRef> workerRef =
       WeakWorkerRef::Create(aWorkerPrivate, [r]() {
         r->Shutdown(r->mWorkerRef->GetPrivate());
@@ -200,38 +226,38 @@ public:
       return nullptr;
     }
 
     r->mWorkerRef = std::move(workerRef);
 
     return r.forget();
   }
 
-  AbortSignal*
+  AbortSignalImpl*
   GetAbortSignalForMainThread()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     if (!mSignalProxy) {
       return nullptr;
     }
 
-    return mSignalProxy->GetOrCreateSignalForMainThread();
+    return mSignalProxy->GetOrCreateSignalImplForMainThread();
   }
 
-  AbortSignal*
+  AbortSignalImpl*
   GetAbortSignalForTargetThread()
   {
     mPromiseProxy->GetWorkerPrivate()->AssertIsOnWorkerThread();
 
     if (!mSignalProxy) {
       return nullptr;
     }
 
-    return mSignalProxy->GetSignalForTargetThread();
+    return mSignalProxy->GetSignalImplForTargetThread();
   }
 
   PromiseWorkerProxy*
   PromiseProxy() const
   {
     MOZ_ASSERT(NS_IsMainThread());
     return mPromiseProxy;
   }
@@ -302,28 +328,28 @@ private:
   FlushConsoleReport() override;
 };
 
 class MainThreadFetchResolver final : public FetchDriverObserver
 {
   RefPtr<Promise> mPromise;
   RefPtr<Response> mResponse;
   RefPtr<FetchObserver> mFetchObserver;
-  RefPtr<AbortSignal> mSignal;
+  RefPtr<AbortSignalImpl> mSignalImpl;
   const bool mMozErrors;
 
   nsCOMPtr<nsILoadGroup> mLoadGroup;
 
   NS_DECL_OWNINGTHREAD
 public:
   MainThreadFetchResolver(Promise* aPromise, FetchObserver* aObserver,
-                          AbortSignal* aSignal, bool aMozErrors)
+                          AbortSignalImpl* aSignalImpl, bool aMozErrors)
     : mPromise(aPromise)
     , mFetchObserver(aObserver)
-    , mSignal(aSignal)
+    , mSignalImpl(aSignalImpl)
     , mMozErrors(aMozErrors)
   {}
 
   void
   OnResponseAvailableInternal(InternalResponse* aResponse) override;
 
   void SetLoadGroup(nsILoadGroup* aLoadGroup)
   {
@@ -410,21 +436,22 @@ public:
         proxy->GetWorkerPrivate()->GetBaseURI()->GetAsciiSpec(spec);
       }
       fetch->SetWorkerScript(spec);
 
       fetch->SetClientInfo(mClientInfo);
       fetch->SetController(mController);
     }
 
-    RefPtr<AbortSignal> signal = mResolver->GetAbortSignalForMainThread();
+    RefPtr<AbortSignalImpl> signalImpl =
+      mResolver->GetAbortSignalForMainThread();
 
     // ...but release it before calling Fetch, because mResolver's callback can
     // be called synchronously and they want the mutex, too.
-    return fetch->Fetch(signal, mResolver);
+    return fetch->Fetch(signalImpl, mResolver);
   }
 };
 
 already_AddRefed<Promise>
 FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
              const RequestInit& aInit, CallerType aCallerType, ErrorResult& aRv)
 {
   RefPtr<Promise> p = Promise::Create(aGlobal, aRv);
@@ -451,27 +478,27 @@ FetchRequest(nsIGlobalObject* aGlobal, c
   GlobalObject global(cx, jsGlobal);
 
   RefPtr<Request> request = Request::Constructor(global, aInput, aInit, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   RefPtr<InternalRequest> r = request->GetInternalRequest();
-  RefPtr<AbortSignal> signal = request->GetSignal();
+  RefPtr<AbortSignalImpl> signalImpl = request->GetSignalImpl();
 
-  if (signal && signal->Aborted()) {
+  if (signalImpl && signalImpl->Aborted()) {
     // Already aborted signal rejects immediately.
     aRv.Throw(NS_ERROR_DOM_ABORT_ERR);
     return nullptr;
   }
 
   RefPtr<FetchObserver> observer;
   if (aInit.mObserve.WasPassed()) {
-    observer = new FetchObserver(aGlobal, signal);
+    observer = new FetchObserver(aGlobal, signalImpl);
     aInit.mObserve.Value().HandleEvent(*observer);
   }
 
   if (NS_IsMainThread()) {
     nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal);
     nsCOMPtr<nsIDocument> doc;
     nsCOMPtr<nsILoadGroup> loadGroup;
     nsIPrincipal* principal;
@@ -500,40 +527,41 @@ FetchRequest(nsIGlobalObject* aGlobal, c
         aRv.Throw(rv);
         return nullptr;
       }
     }
 
     Telemetry::Accumulate(Telemetry::FETCH_IS_MAINTHREAD, 1);
 
     RefPtr<MainThreadFetchResolver> resolver =
-      new MainThreadFetchResolver(p, observer, signal, request->MozErrors());
+      new MainThreadFetchResolver(p, observer, signalImpl,
+                                  request->MozErrors());
     RefPtr<FetchDriver> fetch =
       new FetchDriver(r, principal, loadGroup,
                       aGlobal->EventTargetFor(TaskCategory::Other),
                       nullptr, // PerformanceStorage
                       isTrackingFetch);
     fetch->SetDocument(doc);
     resolver->SetLoadGroup(loadGroup);
-    aRv = fetch->Fetch(signal, resolver);
+    aRv = fetch->Fetch(signalImpl, resolver);
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
   } else {
     WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
     MOZ_ASSERT(worker);
 
     Telemetry::Accumulate(Telemetry::FETCH_IS_MAINTHREAD, 0);
 
     if (worker->IsServiceWorker()) {
       r->SetSkipServiceWorker();
     }
 
     RefPtr<WorkerFetchResolver> resolver =
-      WorkerFetchResolver::Create(worker, p, signal, observer);
+      WorkerFetchResolver::Create(worker, p, signalImpl, observer);
     if (!resolver) {
       NS_WARNING("Could not keep the worker alive.");
       aRv.Throw(NS_ERROR_DOM_ABORT_ERR);
       return nullptr;
     }
 
     Maybe<ClientInfo> clientInfo(worker->GetClientInfo());
     if (clientInfo.isNothing()) {
@@ -557,17 +585,17 @@ MainThreadFetchResolver::OnResponseAvail
   AssertIsOnMainThread();
 
   if (aResponse->Type() != ResponseType::Error) {
     if (mFetchObserver) {
       mFetchObserver->SetState(FetchState::Complete);
     }
 
     nsCOMPtr<nsIGlobalObject> go = mPromise->GetParentObject();
-    mResponse = new Response(go, aResponse, mSignal);
+    mResponse = new Response(go, aResponse, mSignalImpl);
     mPromise->MaybeResolve(mResponse);
   } else {
     if (mFetchObserver) {
       mFetchObserver->SetState(FetchState::Errored);
     }
 
     if (mMozErrors) {
       mPromise->MaybeReject(aResponse->GetErrorCode());
@@ -1145,18 +1173,18 @@ template
 void
 FetchBody<Response>::SetBodyUsed(JSContext* aCx, ErrorResult& aRv);
 
 template <class Derived>
 already_AddRefed<Promise>
 FetchBody<Derived>::ConsumeBody(JSContext* aCx, FetchConsumeType aType,
                                 ErrorResult& aRv)
 {
-  RefPtr<AbortSignal> signal = DerivedClass()->GetSignal();
-  if (signal && signal->Aborted()) {
+  RefPtr<AbortSignalImpl> signalImpl = DerivedClass()->GetSignalImpl();
+  if (signalImpl && signalImpl->Aborted()) {
     aRv.Throw(NS_ERROR_DOM_ABORT_ERR);
     return nullptr;
   }
 
   if (BodyUsed()) {
     aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
     return nullptr;
   }
@@ -1165,17 +1193,17 @@ FetchBody<Derived>::ConsumeBody(JSContex
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   nsCOMPtr<nsIGlobalObject> global = DerivedClass()->GetParentObject();
 
   RefPtr<Promise> promise =
     FetchBodyConsumer<Derived>::Create(global, mMainThreadEventTarget, this,
-                                       signal, aType, aRv);
+                                       signalImpl, aType, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   return promise.forget();
 }
 
 template
@@ -1219,27 +1247,27 @@ FetchBody<Response>::SetMimeType();
 template <class Derived>
 void
 FetchBody<Derived>::SetReadableStreamBody(JSContext* aCx, JSObject* aBody)
 {
   MOZ_ASSERT(!mReadableStreamBody);
   MOZ_ASSERT(aBody);
   mReadableStreamBody = aBody;
 
-  RefPtr<AbortSignal> signal = DerivedClass()->GetSignal();
-  if (!signal) {
+  RefPtr<AbortSignalImpl> signalImpl = DerivedClass()->GetSignalImpl();
+  if (!signalImpl) {
     return;
   }
 
-  bool aborted = signal->Aborted();
+  bool aborted = signalImpl->Aborted();
   if (aborted) {
     JS::Rooted<JSObject*> body(aCx, mReadableStreamBody);
     AbortStream(aCx, body);
   } else if (!IsFollowing()) {
-    Follow(signal);
+    Follow(signalImpl);
   }
 }
 
 template
 void
 FetchBody<Request>::SetReadableStreamBody(JSContext* aCx, JSObject* aBody);
 
 template
@@ -1277,22 +1305,22 @@ FetchBody<Derived>::GetBody(JSContext* a
   // If the body has been already consumed, we lock the stream.
   if (BodyUsed()) {
     LockStream(aCx, body, aRv);
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
   }
 
-  RefPtr<AbortSignal> signal = DerivedClass()->GetSignal();
-  if (signal) {
-    if (signal->Aborted()) {
+  RefPtr<AbortSignalImpl> signalImpl = DerivedClass()->GetSignalImpl();
+  if (signalImpl) {
+    if (signalImpl->Aborted()) {
       AbortStream(aCx, body);
     } else if (!IsFollowing()) {
-      Follow(signal);
+      Follow(signalImpl);
     }
   }
 
   mReadableStreamBody = body;
   aBodyOut.set(mReadableStreamBody);
 }
 
 template
--- a/dom/fetch/Fetch.h
+++ b/dom/fetch/Fetch.h
@@ -244,18 +244,18 @@ public:
   }
 
   void
   MarkAsRead() override
   {
     mBodyUsed = true;
   }
 
-  virtual AbortSignal*
-  GetSignal() const = 0;
+  virtual AbortSignalImpl*
+  GetSignalImpl() const = 0;
 
   // AbortFollower
   void
   Abort() override;
 
 protected:
   nsCOMPtr<nsIGlobalObject> mOwner;
 
--- a/dom/fetch/FetchConsumer.cpp
+++ b/dom/fetch/FetchConsumer.cpp
@@ -333,17 +333,17 @@ NS_INTERFACE_MAP_END
 
 } // anonymous
 
 template <class Derived>
 /* static */ already_AddRefed<Promise>
 FetchBodyConsumer<Derived>::Create(nsIGlobalObject* aGlobal,
                                    nsIEventTarget* aMainThreadEventTarget,
                                    FetchBody<Derived>* aBody,
-                                   AbortSignal* aSignal,
+                                   AbortSignalImpl* aSignalImpl,
                                    FetchConsumeType aType,
                                    ErrorResult& aRv)
 {
   MOZ_ASSERT(aBody);
   MOZ_ASSERT(aMainThreadEventTarget);
 
   nsCOMPtr<nsIInputStream> bodyStream;
   aBody->DerivedClass()->GetBody(getter_AddRefs(bodyStream));
@@ -401,18 +401,18 @@ FetchBodyConsumer<Derived>::Create(nsIGl
 
   nsCOMPtr<nsIRunnable> r =
     new BeginConsumeBodyRunnable<Derived>(consumer, workerRef);
   aRv = aMainThreadEventTarget->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
-  if (aSignal) {
-    consumer->Follow(aSignal);
+  if (aSignalImpl) {
+    consumer->Follow(aSignalImpl);
   }
 
   return promise.forget();
 }
 
 template <class Derived>
 void
 FetchBodyConsumer<Derived>::ReleaseObject()
--- a/dom/fetch/FetchConsumer.h
+++ b/dom/fetch/FetchConsumer.h
@@ -34,17 +34,17 @@ class FetchBodyConsumer final : public n
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   static already_AddRefed<Promise>
   Create(nsIGlobalObject* aGlobal,
          nsIEventTarget* aMainThreadEventTarget,
          FetchBody<Derived>* aBody,
-         AbortSignal* aSignal,
+         AbortSignalImpl* aSignalImpl,
          FetchConsumeType aType,
          ErrorResult& aRv);
 
   void
   ReleaseObject();
 
   void
   BeginConsumeBodyMainThread(ThreadSafeWorkerRef* aWorkerRef);
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -357,17 +357,17 @@ FetchDriver::~FetchDriver()
   AssertIsOnMainThread();
 
   // We assert this since even on failures, we should call
   // FailWithNetworkError().
   MOZ_ASSERT(mResponseAvailableCalled);
 }
 
 nsresult
-FetchDriver::Fetch(AbortSignal* aSignal, FetchDriverObserver* aObserver)
+FetchDriver::Fetch(AbortSignalImpl* aSignalImpl, FetchDriverObserver* aObserver)
 {
   AssertIsOnMainThread();
 #ifdef DEBUG
   MOZ_ASSERT(!mFetchCalled);
   mFetchCalled = true;
 #endif
 
   mObserver = aObserver;
@@ -386,23 +386,23 @@ FetchDriver::Fetch(AbortSignal* aSignal,
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   mRequest->SetPrincipalInfo(std::move(principalInfo));
 
   // If the signal is aborted, it's time to inform the observer and terminate
   // the operation.
-  if (aSignal) {
-    if (aSignal->Aborted()) {
+  if (aSignalImpl) {
+    if (aSignalImpl->Aborted()) {
       Abort();
       return NS_OK;
     }
 
-    Follow(aSignal);
+    Follow(aSignalImpl);
   }
 
   rv = HttpFetch(mRequest->GetPreferredAlternativeDataType());
   if (NS_FAILED(rv)) {
     FailWithNetworkError(rv);
   }
 
   // Any failure is handled by FailWithNetworkError notifying the aObserver.
--- a/dom/fetch/FetchDriver.h
+++ b/dom/fetch/FetchDriver.h
@@ -108,17 +108,17 @@ public:
 
   FetchDriver(InternalRequest* aRequest,
               nsIPrincipal* aPrincipal,
               nsILoadGroup* aLoadGroup,
               nsIEventTarget* aMainThreadEventTarget,
               PerformanceStorage* aPerformanceStorage,
               bool aIsTrackingFetch);
 
-  nsresult Fetch(AbortSignal* aSignal,
+  nsresult Fetch(AbortSignalImpl* aSignalImpl,
                  FetchDriverObserver* aObserver);
 
   void
   SetDocument(nsIDocument* aDocument);
 
   void
   SetClientInfo(const ClientInfo& aClientInfo);
 
--- a/dom/fetch/FetchObserver.cpp
+++ b/dom/fetch/FetchObserver.cpp
@@ -22,22 +22,22 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FetchObserver)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(FetchObserver, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(FetchObserver, DOMEventTargetHelper)
 
 FetchObserver::FetchObserver(nsIGlobalObject* aGlobal,
-                             AbortSignal* aSignal)
+                             AbortSignalImpl* aSignalImpl)
   : DOMEventTargetHelper(aGlobal)
   , mState(FetchState::Requesting)
 {
-  if (aSignal) {
-    Follow(aSignal);
+  if (aSignalImpl) {
+    Follow(aSignalImpl);
   }
 }
 
 JSObject*
 FetchObserver::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return FetchObserver_Binding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/fetch/FetchObserver.h
+++ b/dom/fetch/FetchObserver.h
@@ -16,17 +16,17 @@ namespace dom {
 
 class FetchObserver final : public DOMEventTargetHelper
                           , public AbortFollower
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FetchObserver, DOMEventTargetHelper)
 
-  FetchObserver(nsIGlobalObject* aGlobal, AbortSignal* aSignal);
+  FetchObserver(nsIGlobalObject* aGlobal, AbortSignalImpl* aSignalImpl);
 
   JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   FetchState
   State() const;
 
   IMPL_EVENT_HANDLER(statechange);
--- a/dom/fetch/Request.cpp
+++ b/dom/fetch/Request.cpp
@@ -59,17 +59,17 @@ Request::Request(nsIGlobalObject* aOwner
   MOZ_ASSERT(aRequest->Headers()->Guard() == HeadersGuardEnum::Immutable ||
              aRequest->Headers()->Guard() == HeadersGuardEnum::Request ||
              aRequest->Headers()->Guard() == HeadersGuardEnum::Request_no_cors);
   SetMimeType();
 
   if (aSignal) {
     // If we don't have a signal as argument, we will create it when required by
     // content, otherwise the Request's signal must follow what has been passed.
-    mSignal = new AbortSignal(aSignal->Aborted());
+    mSignal = new AbortSignal(aOwner, aSignal->Aborted());
     if (!mSignal->Aborted()) {
       mSignal->Follow(aSignal);
     }
   }
 }
 
 Request::~Request()
 {
@@ -621,22 +621,22 @@ Request::Headers_()
 
   return mHeaders;
 }
 
 AbortSignal*
 Request::GetOrCreateSignal()
 {
   if (!mSignal) {
-    mSignal = new AbortSignal(false);
+    mSignal = new AbortSignal(mOwner, false);
   }
 
   return mSignal;
 }
 
-AbortSignal*
-Request::GetSignal() const
+AbortSignalImpl*
+Request::GetSignalImpl() const
 {
   return mSignal;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/fetch/Request.h
+++ b/dom/fetch/Request.h
@@ -162,19 +162,19 @@ public:
   GetPrincipalInfo() const
   {
     return mRequest->GetPrincipalInfo();
   }
 
   AbortSignal*
   GetOrCreateSignal();
 
-  // This can return a null AbortSignal.
-  AbortSignal*
-  GetSignal() const override;
+  // This can return a null AbortSignalImpl.
+  AbortSignalImpl*
+  GetSignalImpl() const override;
 
 private:
   ~Request();
 
   RefPtr<InternalRequest> mRequest;
 
   // Lazily created.
   RefPtr<Headers> mHeaders;
--- a/dom/fetch/Response.cpp
+++ b/dom/fetch/Response.cpp
@@ -32,49 +32,49 @@ namespace dom {
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Response)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Response)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(Response)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Response)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mHeaders)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSignal)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSignalImpl)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchStreamReader)
 
   tmp->mReadableStreamBody = nullptr;
   tmp->mReadableStreamReader = nullptr;
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Response)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHeaders)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSignal)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSignalImpl)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchStreamReader)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Response)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mReadableStreamBody)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mReadableStreamReader)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Response)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 Response::Response(nsIGlobalObject* aGlobal,
                    InternalResponse* aInternalResponse,
-                   AbortSignal* aSignal)
+                   AbortSignalImpl* aSignalImpl)
   : FetchBody<Response>(aGlobal)
   , mInternalResponse(aInternalResponse)
-  , mSignal(aSignal)
+  , mSignalImpl(aSignalImpl)
 {
   MOZ_ASSERT(aInternalResponse->Headers()->Guard() == HeadersGuardEnum::Immutable ||
              aInternalResponse->Headers()->Guard() == HeadersGuardEnum::Response);
   SetMimeType();
 
   mozilla::HoldJSObjects(this);
 }
 
@@ -339,17 +339,17 @@ Response::Clone(JSContext* aCx, ErrorRes
   MOZ_ASSERT_IF(body, streamReader);
   MOZ_ASSERT_IF(body, inputStream);
 
   RefPtr<InternalResponse> ir =
     mInternalResponse->Clone(body
       ? InternalResponse::eDontCloneInputStream
       : InternalResponse::eCloneInputStream);
 
-  RefPtr<Response> response = new Response(mOwner, ir, mSignal);
+  RefPtr<Response> response = new Response(mOwner, ir, GetSignalImpl());
 
   if (body) {
     // Maybe we have a body, but we receive null from MaybeTeeReadableStreamBody
     // if this body is a native stream.   In this case the InternalResponse will
     // have a clone of the native body and the ReadableStream will be created
     // lazily if needed.
     response->SetReadableStreamBody(aCx, body);
     response->mFetchStreamReader = streamReader;
@@ -382,17 +382,17 @@ Response::CloneUnfiltered(JSContext* aCx
   MOZ_ASSERT_IF(body, inputStream);
 
   RefPtr<InternalResponse> clone =
     mInternalResponse->Clone(body
       ? InternalResponse::eDontCloneInputStream
       : InternalResponse::eCloneInputStream);
 
   RefPtr<InternalResponse> ir = clone->Unfiltered();
-  RefPtr<Response> ref = new Response(mOwner, ir, mSignal);
+  RefPtr<Response> ref = new Response(mOwner, ir, GetSignalImpl());
 
   if (body) {
     // Maybe we have a body, but we receive null from MaybeTeeReadableStreamBody
     // if this body is a native stream.   In this case the InternalResponse will
     // have a clone of the native body and the ReadableStream will be created
     // lazily if needed.
     ref->SetReadableStreamBody(aCx, body);
     ref->mFetchStreamReader = streamReader;
--- a/dom/fetch/Response.h
+++ b/dom/fetch/Response.h
@@ -29,17 +29,17 @@ class Response final : public nsISupport
                      , public FetchBody<Response>
                      , public nsWrapperCache
 {
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Response)
 
 public:
   Response(nsIGlobalObject* aGlobal, InternalResponse* aInternalResponse,
-           AbortSignal* aSignal);
+           AbortSignalImpl* aSignalImpl);
 
   Response(const Response& aOther) = delete;
 
   JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
   {
     return Response_Binding::Wrap(aCx, this, aGivenProto);
   }
@@ -135,27 +135,27 @@ public:
   CloneUnfiltered(JSContext* aCx, ErrorResult& aRv);
 
   void
   SetBody(nsIInputStream* aBody, int64_t aBodySize);
 
   already_AddRefed<InternalResponse>
   GetInternalResponse() const;
 
-  AbortSignal*
-  GetSignal() const override
+  AbortSignalImpl*
+  GetSignalImpl() const override
   {
-    return mSignal;
+    return mSignalImpl;
   }
 
 private:
   ~Response();
 
   RefPtr<InternalResponse> mInternalResponse;
   // Lazily created
   RefPtr<Headers> mHeaders;
-  RefPtr<AbortSignal> mSignal;
+  RefPtr<AbortSignalImpl> mSignalImpl;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_Response_h