From a04d67dd12d4999b28e74744150770482a3c5a3d Mon Sep 17 00:00:00 2001 From: Moonchild Date: Wed, 10 Jun 2020 21:51:44 +0000 Subject: Issue #1587 - Part 3: Hook FetchSignal up to the Fetch API --- dom/fetch/Fetch.cpp | 158 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 141 insertions(+), 17 deletions(-) (limited to 'dom/fetch/Fetch.cpp') diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index f944352e3..11e93205c 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -52,41 +52,137 @@ namespace dom { using namespace workers; +// This class helps the proxying of FetchSignal changes cross threads. +class FetchSignalProxy final : public FetchSignal::Follower +{ + // This is created and released on the main-thread. + RefPtr mSignalMainThread; + + // This value is used only for the creation of FetchSignal on the + // main-thread. They are not updated. + const bool mAborted; + + // This runnable propagates changes from the FetchSignal on workers to the + // FetchSignal on main-thread. + class FetchSignalProxyRunnable final : public Runnable + { + RefPtr mProxy; + + public: + explicit FetchSignalProxyRunnable(FetchSignalProxy* aProxy) + : mProxy(aProxy) + {} + + NS_IMETHOD + Run() override + { + MOZ_ASSERT(NS_IsMainThread()); + FetchSignal* signal = mProxy->GetOrCreateSignalForMainThread(); + signal->Abort(); + return NS_OK; + } + }; + +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchSignalProxy) + + explicit FetchSignalProxy(FetchSignal* aSignal) + : mAborted(aSignal->Aborted()) + { + Follow(aSignal); + } + + void + Aborted() override + { + RefPtr runnable = + new FetchSignalProxyRunnable(this); + NS_DispatchToMainThread(runnable); + } + + FetchSignal* + GetOrCreateSignalForMainThread() + { + MOZ_ASSERT(NS_IsMainThread()); + if (!mSignalMainThread) { + mSignalMainThread = new FetchSignal(mAborted); + } + return mSignalMainThread; + } + + void + Shutdown() + { + Unfollow(); + } + +private: + ~FetchSignalProxy() + { + NS_ReleaseOnMainThread(mSignalMainThread.forget()); + } +}; + class WorkerFetchResolver final : public FetchDriverObserver { friend class MainThreadFetchRunnable; + friend class WorkerFetchResponseEndBase; friend class WorkerFetchResponseEndRunnable; friend class WorkerFetchResponseRunnable; RefPtr mPromiseProxy; + RefPtr mSignalProxy; + public: // Returns null if worker is shutting down. static already_AddRefed - Create(workers::WorkerPrivate* aWorkerPrivate, Promise* aPromise) + Create(workers::WorkerPrivate* aWorkerPrivate, Promise* aPromise, + FetchSignal* aSignal) { MOZ_ASSERT(aWorkerPrivate); aWorkerPrivate->AssertIsOnWorkerThread(); - RefPtr proxy = PromiseWorkerProxy::Create(aWorkerPrivate, aPromise); + RefPtr proxy = + PromiseWorkerProxy::Create(aWorkerPrivate, aPromise); if (!proxy) { return nullptr; } - RefPtr r = new WorkerFetchResolver(proxy); + RefPtr signalProxy; + if (aSignal) { + signalProxy = new FetchSignalProxy(aSignal); + } + + RefPtr r = new WorkerFetchResolver(proxy, signalProxy); return r.forget(); } + FetchSignal* + GetFetchSignal() + { + MOZ_ASSERT(NS_IsMainThread()); + + if (!mSignalProxy) { + return nullptr; + } + + return mSignalProxy->GetOrCreateSignalForMainThread(); + } + void OnResponseAvailableInternal(InternalResponse* aResponse) override; void - OnResponseEnd() override; + OnResponseEnd(FetchDriverObserver::EndReason eReason) override; private: - explicit WorkerFetchResolver(PromiseWorkerProxy* aProxy) + WorkerFetchResolver(PromiseWorkerProxy* aProxy, + FetchSignalProxy* aSignalProxy) : mPromiseProxy(aProxy) + , mSignalProxy(aSignalProxy) { MOZ_ASSERT(!NS_IsMainThread()); MOZ_ASSERT(mPromiseProxy); + } ~WorkerFetchResolver() @@ -115,8 +211,12 @@ public: mDocument = aDocument; } - virtual void OnResponseEnd() override + void OnResponseEnd(FetchDriverObserver::EndReason aReason) override { + if (aReason == eAborted) { + mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR); + } + FlushConsoleReport(); } @@ -170,9 +270,11 @@ public: fetch->SetWorkerScript(spec); } + RefPtr signal = mResolver->GetFetchSignal(); + // ...but release it before calling Fetch, because mResolver's callback can // be called synchronously and they want the mutex, too. - return fetch->Fetch(mResolver); + return fetch->Fetch(signal, mResolver); } }; @@ -210,6 +312,12 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput, RefPtr r = request->GetInternalRequest(); + RefPtr signal; + if (aInit.mSignal.WasPassed()) { + signal = &aInit.mSignal.Value(); + // Let's FetchDriver to deal with an already aborted signal. + } + if (NS_IsMainThread()) { nsCOMPtr window = do_QueryInterface(aGlobal); nsCOMPtr doc; @@ -240,7 +348,7 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput, RefPtr fetch = new FetchDriver(r, principal, loadGroup); fetch->SetDocument(doc); resolver->SetDocument(doc); - aRv = fetch->Fetch(resolver); + aRv = fetch->Fetch(signal, resolver); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } @@ -252,7 +360,7 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput, r->SetSkipServiceWorker(); } - RefPtr resolver = WorkerFetchResolver::Create(worker, p); + RefPtr resolver = WorkerFetchResolver::Create(worker, p, signal); if (!resolver) { NS_WARNING("Could not add WorkerFetchResolver workerHolder to worker"); aRv.Throw(NS_ERROR_DOM_ABORT_ERR); @@ -306,6 +414,7 @@ public: , mResolver(aResolver) , mInternalResponse(aResponse) { + MOZ_ASSERT(mResolver); } bool @@ -332,9 +441,13 @@ public: class WorkerFetchResponseEndBase { RefPtr mPromiseProxy; + RefPtr mSignalProxy; + public: - explicit WorkerFetchResponseEndBase(PromiseWorkerProxy* aPromiseProxy) + WorkerFetchResponseEndBase(PromiseWorkerProxy* aPromiseProxy, + FetchSignalProxy* aSignalProxy) : mPromiseProxy(aPromiseProxy) + , mSignalProxy(aSignalProxy) { MOZ_ASSERT(mPromiseProxy); } @@ -344,7 +457,16 @@ public: { MOZ_ASSERT(aWorkerPrivate); aWorkerPrivate->AssertIsOnWorkerThread(); + + RefPtr promise = mPromiseProxy->WorkerPromise(); + promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR); + mPromiseProxy->CleanUp(); + + if (mSignalProxy) { + mSignalProxy->Shutdown(); + mSignalProxy = nullptr; + } } }; @@ -352,9 +474,10 @@ class WorkerFetchResponseEndRunnable final : public MainThreadWorkerRunnable , public WorkerFetchResponseEndBase { public: - explicit WorkerFetchResponseEndRunnable(PromiseWorkerProxy* aPromiseProxy) + WorkerFetchResponseEndRunnable(PromiseWorkerProxy* aPromiseProxy, + FetchSignalProxy* aSignalProxy) : MainThreadWorkerRunnable(aPromiseProxy->GetWorkerPrivate()) - , WorkerFetchResponseEndBase(aPromiseProxy) + , WorkerFetchResponseEndBase(aPromiseProxy, aSignalProxy) { } @@ -379,9 +502,10 @@ class WorkerFetchResponseEndControlRunnable final : public MainThreadWorkerContr , public WorkerFetchResponseEndBase { public: - explicit WorkerFetchResponseEndControlRunnable(PromiseWorkerProxy* aPromiseProxy) + WorkerFetchResponseEndControlRunnable(PromiseWorkerProxy* aPromiseProxy, + FetchSignalProxy* aSignalProxy) : MainThreadWorkerControlRunnable(aPromiseProxy->GetWorkerPrivate()) - , WorkerFetchResponseEndBase(aPromiseProxy) + , WorkerFetchResponseEndBase(aPromiseProxy, aSignalProxy) { } @@ -415,7 +539,7 @@ WorkerFetchResolver::OnResponseAvailableInternal(InternalResponse* aResponse) } void -WorkerFetchResolver::OnResponseEnd() +WorkerFetchResolver::OnResponseEnd(FetchDriverObserver::EndReason aReason) { AssertIsOnMainThread(); MutexAutoLock lock(mPromiseProxy->Lock()); @@ -426,11 +550,11 @@ WorkerFetchResolver::OnResponseEnd() FlushConsoleReport(); RefPtr r = - new WorkerFetchResponseEndRunnable(mPromiseProxy); + new WorkerFetchResponseEndRunnable(mPromiseProxy, mSignalProxy); if (!r->Dispatch()) { RefPtr cr = - new WorkerFetchResponseEndControlRunnable(mPromiseProxy); + new WorkerFetchResponseEndControlRunnable(mPromiseProxy, mSignalProxy); // This can fail if the worker thread is canceled or killed causing // the PromiseWorkerProxy to give up its WorkerHolder immediately, // allowing the worker thread to become Dead. -- cgit v1.2.3 From bb7060582934f087b71702d1e83f762d5fd6f0af Mon Sep 17 00:00:00 2001 From: Moonchild Date: Thu, 11 Jun 2020 08:51:07 +0000 Subject: Issue #1587 - Part 5: Hook FetchObserver up to the Fetch API --- dom/fetch/Fetch.cpp | 170 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 135 insertions(+), 35 deletions(-) (limited to 'dom/fetch/Fetch.cpp') diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index 11e93205c..04aa7fd91 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -39,6 +39,7 @@ #include "mozilla/dom/URLSearchParams.h" #include "mozilla/dom/workers/ServiceWorkerManager.h" +#include "FetchObserver.h" #include "InternalRequest.h" #include "InternalResponse.h" @@ -126,18 +127,20 @@ private: class WorkerFetchResolver final : public FetchDriverObserver { friend class MainThreadFetchRunnable; + friend class WorkerDataAvailableRunnable; friend class WorkerFetchResponseEndBase; friend class WorkerFetchResponseEndRunnable; friend class WorkerFetchResponseRunnable; RefPtr mPromiseProxy; RefPtr mSignalProxy; + RefPtr mFetchObserver; public: // Returns null if worker is shutting down. static already_AddRefed Create(workers::WorkerPrivate* aWorkerPrivate, Promise* aPromise, - FetchSignal* aSignal) + FetchSignal* aSignal, FetchObserver* aObserver) { MOZ_ASSERT(aWorkerPrivate); aWorkerPrivate->AssertIsOnWorkerThread(); @@ -152,7 +155,8 @@ public: signalProxy = new FetchSignalProxy(aSignal); } - RefPtr r = new WorkerFetchResolver(proxy, signalProxy); + RefPtr r = + new WorkerFetchResolver(proxy, signalProxy, aObserver); return r.forget(); } @@ -174,15 +178,19 @@ public: void OnResponseEnd(FetchDriverObserver::EndReason eReason) override; + void + OnDataAvailable() override; + private: WorkerFetchResolver(PromiseWorkerProxy* aProxy, - FetchSignalProxy* aSignalProxy) + FetchSignalProxy* aSignalProxy, + FetchObserver* aObserver) : mPromiseProxy(aProxy) , mSignalProxy(aSignalProxy) + , mFetchObserver(aObserver) { MOZ_ASSERT(!NS_IsMainThread()); MOZ_ASSERT(mPromiseProxy); - } ~WorkerFetchResolver() @@ -196,12 +204,16 @@ class MainThreadFetchResolver final : public FetchDriverObserver { RefPtr mPromise; RefPtr mResponse; + RefPtr mFetchObserver; nsCOMPtr mDocument; NS_DECL_OWNINGTHREAD public: - explicit MainThreadFetchResolver(Promise* aPromise); + MainThreadFetchResolver(Promise* aPromise, FetchObserver* aObserver) + : mPromise(aPromise) + , mFetchObserver(aObserver) + {} void OnResponseAvailableInternal(InternalResponse* aResponse) override; @@ -217,9 +229,14 @@ public: mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR); } + mFetchObserver = nullptr; + FlushConsoleReport(); } + void + OnDataAvailable() override; + private: ~MainThreadFetchResolver(); @@ -318,6 +335,12 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput, // Let's FetchDriver to deal with an already aborted signal. } + RefPtr observer; + if (aInit.mObserve.WasPassed()) { + observer = new FetchObserver(aGlobal, signal); + aInit.mObserve.Value().HandleEvent(*observer); + } + if (NS_IsMainThread()) { nsCOMPtr window = do_QueryInterface(aGlobal); nsCOMPtr doc; @@ -344,7 +367,8 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput, } } - RefPtr resolver = new MainThreadFetchResolver(p); + RefPtr resolver = + new MainThreadFetchResolver(p, observer); RefPtr fetch = new FetchDriver(r, principal, loadGroup); fetch->SetDocument(doc); resolver->SetDocument(doc); @@ -360,7 +384,8 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput, r->SetSkipServiceWorker(); } - RefPtr resolver = WorkerFetchResolver::Create(worker, p, signal); + RefPtr resolver = + WorkerFetchResolver::Create(worker, p, signal, observer); if (!resolver) { NS_WARNING("Could not add WorkerFetchResolver workerHolder to worker"); aRv.Throw(NS_ERROR_DOM_ABORT_ERR); @@ -374,11 +399,6 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput, return p.forget(); } -MainThreadFetchResolver::MainThreadFetchResolver(Promise* aPromise) - : mPromise(aPromise) -{ -} - void MainThreadFetchResolver::OnResponseAvailableInternal(InternalResponse* aResponse) { @@ -386,16 +406,39 @@ MainThreadFetchResolver::OnResponseAvailableInternal(InternalResponse* aResponse AssertIsOnMainThread(); if (aResponse->Type() != ResponseType::Error) { + if (mFetchObserver) { + mFetchObserver->SetState(FetchState::Complete); + } + nsCOMPtr go = mPromise->GetParentObject(); mResponse = new Response(go, aResponse); mPromise->MaybeResolve(mResponse); } else { + if (mFetchObserver) { + mFetchObserver->SetState(FetchState::Errored); + } + ErrorResult result; result.ThrowTypeError(); mPromise->MaybeReject(result); } } +void +MainThreadFetchResolver::OnDataAvailable() +{ + NS_ASSERT_OWNINGTHREAD(MainThreadFetchResolver); + AssertIsOnMainThread(); + + if (!mFetchObserver) { + return; + } + + if (mFetchObserver->State() == FetchState::Requesting) { + mFetchObserver->SetState(FetchState::Responding); + } +} + MainThreadFetchResolver::~MainThreadFetchResolver() { NS_ASSERT_OWNINGTHREAD(MainThreadFetchResolver); @@ -426,10 +469,18 @@ public: RefPtr promise = mResolver->mPromiseProxy->WorkerPromise(); if (mInternalResponse->Type() != ResponseType::Error) { + if (mResolver->mFetchObserver) { + mResolver->mFetchObserver->SetState(FetchState::Complete); + } + RefPtr global = aWorkerPrivate->GlobalScope(); RefPtr response = new Response(global, mInternalResponse); promise->MaybeResolve(response); } else { + if (mResolver->mFetchObserver) { + mResolver->mFetchObserver->SetState(FetchState::Errored); + } + ErrorResult result; result.ThrowTypeError(); promise->MaybeReject(result); @@ -438,18 +489,42 @@ public: } }; +class WorkerDataAvailableRunnable final : public MainThreadWorkerRunnable +{ + RefPtr mResolver; +public: + WorkerDataAvailableRunnable(WorkerPrivate* aWorkerPrivate, + WorkerFetchResolver* aResolver) + : MainThreadWorkerRunnable(aWorkerPrivate) + , mResolver(aResolver) + { + } + + bool + WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override + { + MOZ_ASSERT(aWorkerPrivate); + aWorkerPrivate->AssertIsOnWorkerThread(); + + if (mResolver->mFetchObserver && + mResolver->mFetchObserver->State() == FetchState::Requesting) { + mResolver->mFetchObserver->SetState(FetchState::Responding); + } + + return true; + } +}; + class WorkerFetchResponseEndBase { - RefPtr mPromiseProxy; - RefPtr mSignalProxy; +protected: + RefPtr mResolver; public: - WorkerFetchResponseEndBase(PromiseWorkerProxy* aPromiseProxy, - FetchSignalProxy* aSignalProxy) - : mPromiseProxy(aPromiseProxy) - , mSignalProxy(aSignalProxy) + explicit WorkerFetchResponseEndBase(WorkerFetchResolver* aResolver) + : mResolver(aResolver) { - MOZ_ASSERT(mPromiseProxy); + MOZ_ASSERT(aResolver); } void @@ -458,14 +533,13 @@ public: MOZ_ASSERT(aWorkerPrivate); aWorkerPrivate->AssertIsOnWorkerThread(); - RefPtr promise = mPromiseProxy->WorkerPromise(); - promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR); + mResolver->mPromiseProxy->CleanUp(); - mPromiseProxy->CleanUp(); + mResolver->mFetchObserver = nullptr; - if (mSignalProxy) { - mSignalProxy->Shutdown(); - mSignalProxy = nullptr; + if (mResolver->mSignalProxy) { + mResolver->mSignalProxy->Shutdown(); + mResolver->mSignalProxy = nullptr; } } }; @@ -473,17 +547,26 @@ public: class WorkerFetchResponseEndRunnable final : public MainThreadWorkerRunnable , public WorkerFetchResponseEndBase { + FetchDriverObserver::EndReason mReason; + public: - WorkerFetchResponseEndRunnable(PromiseWorkerProxy* aPromiseProxy, - FetchSignalProxy* aSignalProxy) - : MainThreadWorkerRunnable(aPromiseProxy->GetWorkerPrivate()) - , WorkerFetchResponseEndBase(aPromiseProxy, aSignalProxy) + WorkerFetchResponseEndRunnable(WorkerPrivate* aWorkerPrivate, + WorkerFetchResolver* aResolver, + FetchDriverObserver::EndReason aReason) + : MainThreadWorkerRunnable(aWorkerPrivate) + , WorkerFetchResponseEndBase(aResolver) + , mReason(aReason) { } bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { + if (mReason == FetchDriverObserver::eAborted) { + RefPtr promise = mResolver->mPromiseProxy->WorkerPromise(); + promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR); + } + WorkerRunInternal(aWorkerPrivate); return true; } @@ -502,10 +585,10 @@ class WorkerFetchResponseEndControlRunnable final : public MainThreadWorkerContr , public WorkerFetchResponseEndBase { public: - WorkerFetchResponseEndControlRunnable(PromiseWorkerProxy* aPromiseProxy, - FetchSignalProxy* aSignalProxy) - : MainThreadWorkerControlRunnable(aPromiseProxy->GetWorkerPrivate()) - , WorkerFetchResponseEndBase(aPromiseProxy, aSignalProxy) + WorkerFetchResponseEndControlRunnable(WorkerPrivate* aWorkerPrivate, + WorkerFetchResolver* aResolver) + : MainThreadWorkerControlRunnable(aWorkerPrivate) + , WorkerFetchResponseEndBase(aResolver) { } @@ -538,6 +621,21 @@ WorkerFetchResolver::OnResponseAvailableInternal(InternalResponse* aResponse) } } +void +WorkerFetchResolver::OnDataAvailable() +{ + AssertIsOnMainThread(); + + MutexAutoLock lock(mPromiseProxy->Lock()); + if (mPromiseProxy->CleanedUp()) { + return; + } + + RefPtr r = + new WorkerDataAvailableRunnable(mPromiseProxy->GetWorkerPrivate(), this); + Unused << r->Dispatch(); +} + void WorkerFetchResolver::OnResponseEnd(FetchDriverObserver::EndReason aReason) { @@ -550,11 +648,13 @@ WorkerFetchResolver::OnResponseEnd(FetchDriverObserver::EndReason aReason) FlushConsoleReport(); RefPtr r = - new WorkerFetchResponseEndRunnable(mPromiseProxy, mSignalProxy); + new WorkerFetchResponseEndRunnable(mPromiseProxy->GetWorkerPrivate(), + this, aReason); if (!r->Dispatch()) { RefPtr cr = - new WorkerFetchResponseEndControlRunnable(mPromiseProxy, mSignalProxy); + new WorkerFetchResponseEndControlRunnable(mPromiseProxy->GetWorkerPrivate(), + this); // This can fail if the worker thread is canceled or killed causing // the PromiseWorkerProxy to give up its WorkerHolder immediately, // allowing the worker thread to become Dead. -- cgit v1.2.3 From 21403c31e0288ad3c1921019f6f6185a0019a9a4 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Thu, 11 Jun 2020 23:20:52 +0000 Subject: Issue #1587 - Part 7: Rename FetchController to AbortController Also renames FetchSignal to AbortSignal. Includes renaming the various controlling prefs to enable. --- dom/fetch/Fetch.cpp | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'dom/fetch/Fetch.cpp') diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index 04aa7fd91..4dbe2de0a 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -53,24 +53,24 @@ namespace dom { using namespace workers; -// This class helps the proxying of FetchSignal changes cross threads. -class FetchSignalProxy final : public FetchSignal::Follower +// This class helps the proxying of AbortSignal changes cross threads. +class AbortSignalProxy final : public AbortSignal::Follower { // This is created and released on the main-thread. - RefPtr mSignalMainThread; + RefPtr mSignalMainThread; - // This value is used only for the creation of FetchSignal on the + // This value is used only for the creation of AbortSignal on the // main-thread. They are not updated. const bool mAborted; - // This runnable propagates changes from the FetchSignal on workers to the - // FetchSignal on main-thread. - class FetchSignalProxyRunnable final : public Runnable + // This runnable propagates changes from the AbortSignal on workers to the + // AbortSignal on main-thread. + class AbortSignalProxyRunnable final : public Runnable { - RefPtr mProxy; + RefPtr mProxy; public: - explicit FetchSignalProxyRunnable(FetchSignalProxy* aProxy) + explicit AbortSignalProxyRunnable(AbortSignalProxy* aProxy) : mProxy(aProxy) {} @@ -78,16 +78,16 @@ class FetchSignalProxy final : public FetchSignal::Follower Run() override { MOZ_ASSERT(NS_IsMainThread()); - FetchSignal* signal = mProxy->GetOrCreateSignalForMainThread(); + AbortSignal* signal = mProxy->GetOrCreateSignalForMainThread(); signal->Abort(); return NS_OK; } }; public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchSignalProxy) + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbortSignalProxy) - explicit FetchSignalProxy(FetchSignal* aSignal) + explicit AbortSignalProxy(AbortSignal* aSignal) : mAborted(aSignal->Aborted()) { Follow(aSignal); @@ -96,17 +96,17 @@ public: void Aborted() override { - RefPtr runnable = - new FetchSignalProxyRunnable(this); + RefPtr runnable = + new AbortSignalProxyRunnable(this); NS_DispatchToMainThread(runnable); } - FetchSignal* + AbortSignal* GetOrCreateSignalForMainThread() { MOZ_ASSERT(NS_IsMainThread()); if (!mSignalMainThread) { - mSignalMainThread = new FetchSignal(mAborted); + mSignalMainThread = new AbortSignal(mAborted); } return mSignalMainThread; } @@ -118,7 +118,7 @@ public: } private: - ~FetchSignalProxy() + ~AbortSignalProxy() { NS_ReleaseOnMainThread(mSignalMainThread.forget()); } @@ -133,14 +133,14 @@ class WorkerFetchResolver final : public FetchDriverObserver friend class WorkerFetchResponseRunnable; RefPtr mPromiseProxy; - RefPtr mSignalProxy; + RefPtr mSignalProxy; RefPtr mFetchObserver; public: // Returns null if worker is shutting down. static already_AddRefed Create(workers::WorkerPrivate* aWorkerPrivate, Promise* aPromise, - FetchSignal* aSignal, FetchObserver* aObserver) + AbortSignal* aSignal, FetchObserver* aObserver) { MOZ_ASSERT(aWorkerPrivate); aWorkerPrivate->AssertIsOnWorkerThread(); @@ -150,9 +150,9 @@ public: return nullptr; } - RefPtr signalProxy; + RefPtr signalProxy; if (aSignal) { - signalProxy = new FetchSignalProxy(aSignal); + signalProxy = new AbortSignalProxy(aSignal); } RefPtr r = @@ -160,8 +160,8 @@ public: return r.forget(); } - FetchSignal* - GetFetchSignal() + AbortSignal* + GetAbortSignal() { MOZ_ASSERT(NS_IsMainThread()); @@ -183,7 +183,7 @@ public: private: WorkerFetchResolver(PromiseWorkerProxy* aProxy, - FetchSignalProxy* aSignalProxy, + AbortSignalProxy* aSignalProxy, FetchObserver* aObserver) : mPromiseProxy(aProxy) , mSignalProxy(aSignalProxy) @@ -287,7 +287,7 @@ public: fetch->SetWorkerScript(spec); } - RefPtr signal = mResolver->GetFetchSignal(); + RefPtr signal = mResolver->GetAbortSignal(); // ...but release it before calling Fetch, because mResolver's callback can // be called synchronously and they want the mutex, too. @@ -329,7 +329,7 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput, RefPtr r = request->GetInternalRequest(); - RefPtr signal; + RefPtr signal; if (aInit.mSignal.WasPassed()) { signal = &aInit.mSignal.Value(); // Let's FetchDriver to deal with an already aborted signal. -- cgit v1.2.3 From e2403eeb5ac9009b9a7b794059fe6df245cf74dd Mon Sep 17 00:00:00 2001 From: Moonchild Date: Fri, 12 Jun 2020 01:46:48 +0000 Subject: Issue #1587 - Part 9: Immediately reject an already-aborted signal --- dom/fetch/Fetch.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'dom/fetch/Fetch.cpp') diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index 4dbe2de0a..191f4cfc3 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -332,7 +332,12 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput, RefPtr signal; if (aInit.mSignal.WasPassed()) { signal = &aInit.mSignal.Value(); - // Let's FetchDriver to deal with an already aborted signal. + } + + if (signal && signal->Aborted()) { + // An already aborted signal should reject immediately. + aRv.Throw(NS_ERROR_DOM_ABORT_ERR); + return nullptr; } RefPtr observer; -- cgit v1.2.3