Skip to content

Commit 9f4d22f

Browse files
committed
Bug 1826206 - Require nsISerialEventTarget for RetargetDeliveryTo, r=necko-reviewers,valentin
This avoids potential issues where multiple OnDataAvailable callbacks or similar could theoretically be called concurrently on different StreamTransportService threads when targeting the STS - these cases will now target a TaskQueue on the STS instead, structurally ensuring serial execution. Differential Revision: https://phabricator.services.mozilla.com/D179984
1 parent c1f04d7 commit 9f4d22f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+133
-112
lines changed

dom/base/BodyConsumer.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "mozilla/dom/WorkerScope.h"
2424
#include "mozilla/ipc/PBackgroundSharedTypes.h"
2525
#include "mozilla/ScopeExit.h"
26+
#include "mozilla/TaskQueue.h"
2627
#include "nsComponentManagerUtils.h"
2728
#include "nsIFile.h"
2829
#include "nsIThreadRetargetableRequest.h"
@@ -272,7 +273,7 @@ NS_IMPL_ISUPPORTS(ConsumeBodyDoneObserver, nsIStreamLoaderObserver)
272273
} // namespace
273274

274275
/* static */ already_AddRefed<Promise> BodyConsumer::Create(
275-
nsIGlobalObject* aGlobal, nsIEventTarget* aMainThreadEventTarget,
276+
nsIGlobalObject* aGlobal, nsISerialEventTarget* aMainThreadEventTarget,
276277
nsIInputStream* aBodyStream, AbortSignalImpl* aSignalImpl,
277278
ConsumeType aType, const nsACString& aBodyBlobURISpec,
278279
const nsAString& aBodyLocalPath, const nsACString& aBodyMimeType,
@@ -359,10 +360,11 @@ void BodyConsumer::ReleaseObject() {
359360
}
360361

361362
BodyConsumer::BodyConsumer(
362-
nsIEventTarget* aMainThreadEventTarget, nsIGlobalObject* aGlobalObject,
363-
nsIInputStream* aBodyStream, Promise* aPromise, ConsumeType aType,
364-
const nsACString& aBodyBlobURISpec, const nsAString& aBodyLocalPath,
365-
const nsACString& aBodyMimeType, const nsACString& aMixedCaseMimeType,
363+
nsISerialEventTarget* aMainThreadEventTarget,
364+
nsIGlobalObject* aGlobalObject, nsIInputStream* aBodyStream,
365+
Promise* aPromise, ConsumeType aType, const nsACString& aBodyBlobURISpec,
366+
const nsAString& aBodyLocalPath, const nsACString& aBodyMimeType,
367+
const nsACString& aMixedCaseMimeType,
366368
MutableBlobStorage::MutableBlobStorageType aBlobStorageType)
367369
: mTargetThread(NS_GetCurrentThread()),
368370
mMainThreadEventTarget(aMainThreadEventTarget),
@@ -575,7 +577,9 @@ void BodyConsumer::BeginConsumeBodyMainThread(ThreadSafeWorkerRef* aWorkerRef) {
575577
if (rr) {
576578
nsCOMPtr<nsIEventTarget> sts =
577579
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
578-
rv = rr->RetargetDeliveryTo(sts);
580+
RefPtr<TaskQueue> queue =
581+
TaskQueue::Create(sts.forget(), "BodyConsumer STS Delivery Queue");
582+
rv = rr->RetargetDeliveryTo(queue);
579583
if (NS_FAILED(rv)) {
580584
NS_WARNING("Retargeting failed");
581585
}

dom/base/BodyConsumer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class BodyConsumer final : public nsIObserver,
6060
* @param aRv An ErrorResult.
6161
*/
6262
static already_AddRefed<Promise> Create(
63-
nsIGlobalObject* aGlobal, nsIEventTarget* aMainThreadEventTarget,
63+
nsIGlobalObject* aGlobal, nsISerialEventTarget* aMainThreadEventTarget,
6464
nsIInputStream* aBodyStream, AbortSignalImpl* aSignalImpl,
6565
ConsumeType aType, const nsACString& aBodyBlobURISpec,
6666
const nsAString& aBodyLocalPath, const nsACString& aBodyMimeType,
@@ -94,7 +94,7 @@ class BodyConsumer final : public nsIObserver,
9494
void RunAbortAlgorithm() override;
9595

9696
private:
97-
BodyConsumer(nsIEventTarget* aMainThreadEventTarget,
97+
BodyConsumer(nsISerialEventTarget* aMainThreadEventTarget,
9898
nsIGlobalObject* aGlobalObject, nsIInputStream* aBodyStream,
9999
Promise* aPromise, ConsumeType aType,
100100
const nsACString& aBodyBlobURISpec,
@@ -109,7 +109,7 @@ class BodyConsumer final : public nsIObserver,
109109
void AssertIsOnTargetThread() const;
110110

111111
nsCOMPtr<nsIThread> mTargetThread;
112-
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
112+
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
113113

114114
// This is nullified when the consuming of the body starts.
115115
nsCOMPtr<nsIInputStream> mBodyStream;

dom/base/EventSource.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class EventSourceImpl final : public nsIObserver,
7676
public nsIChannelEventSink,
7777
public nsIInterfaceRequestor,
7878
public nsSupportsWeakReference,
79-
public nsIEventTarget,
79+
public nsISerialEventTarget,
8080
public nsITimerCallback,
8181
public nsINamed,
8282
public nsIThreadRetargetableStreamListener {
@@ -364,8 +364,9 @@ class EventSourceImpl final : public nsIObserver,
364364
NS_IMPL_ISUPPORTS(EventSourceImpl, nsIObserver, nsIStreamListener,
365365
nsIRequestObserver, nsIChannelEventSink,
366366
nsIInterfaceRequestor, nsISupportsWeakReference,
367-
nsIEventTarget, nsIThreadRetargetableStreamListener,
368-
nsITimerCallback, nsINamed)
367+
nsISerialEventTarget, nsIEventTarget,
368+
nsIThreadRetargetableStreamListener, nsITimerCallback,
369+
nsINamed)
369370

370371
EventSourceImpl::EventSourceImpl(EventSource* aEventSource,
371372
nsICookieJarSettings* aCookieJarSettings)
@@ -1056,16 +1057,15 @@ nsresult EventSourceImpl::InitChannelAndRequestEventSource(
10561057

10571058
MOZ_ASSERT_IF(mIsMainThread, aEventTargetAccessAllowed);
10581059

1059-
nsresult rv = aEventTargetAccessAllowed
1060-
? [this]() {
1061-
// We can't call GetEventSource() because we're not
1062-
// allowed to touch the refcount off the worker thread
1063-
// due to an assertion, event if it would have otherwise
1064-
// been safe.
1065-
auto lock = mSharedData.Lock();
1066-
return lock->mEventSource->CheckCurrentGlobalCorrectness();
1067-
}()
1068-
: NS_OK;
1060+
nsresult rv = aEventTargetAccessAllowed ? [this]() {
1061+
// We can't call GetEventSource() because we're not
1062+
// allowed to touch the refcount off the worker thread
1063+
// due to an assertion, event if it would have otherwise
1064+
// been safe.
1065+
auto lock = mSharedData.Lock();
1066+
return lock->mEventSource->CheckCurrentGlobalCorrectness();
1067+
}()
1068+
: NS_OK;
10691069
if (NS_FAILED(rv) || !isValidScheme) {
10701070
DispatchFailConnection();
10711071
return NS_ERROR_DOM_SECURITY_ERR;

dom/fetch/Fetch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ class FetchBody : public FetchBodyBase, public AbortFollower {
251251
bool mBodyUsed;
252252

253253
// The main-thread event target for runnable dispatching.
254-
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
254+
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
255255
};
256256

257257
class EmptyBody final : public FetchBody<EmptyBody> {

dom/fetch/FetchDriver.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "js/Value.h"
88
#include "mozilla/DebugOnly.h"
9+
#include "mozilla/TaskQueue.h"
910
#include "mozilla/dom/FetchDriver.h"
1011

1112
#include "mozilla/dom/ReferrerInfo.h"
@@ -1236,7 +1237,9 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest) {
12361237

12371238
// Try to retarget off main thread.
12381239
if (nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(aRequest)) {
1239-
Unused << NS_WARN_IF(NS_FAILED(rr->RetargetDeliveryTo(sts)));
1240+
RefPtr<TaskQueue> queue =
1241+
TaskQueue::Create(sts.forget(), "FetchDriver STS Delivery Queue");
1242+
Unused << NS_WARN_IF(NS_FAILED(rr->RetargetDeliveryTo(queue)));
12401243
}
12411244
return NS_OK;
12421245
}

dom/file/Blob.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ already_AddRefed<Promise> Blob::ConsumeBody(
274274
return nullptr;
275275
}
276276

277-
nsCOMPtr<nsIEventTarget> mainThreadEventTarget;
277+
nsCOMPtr<nsISerialEventTarget> mainThreadEventTarget;
278278
if (!NS_IsMainThread()) {
279279
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
280280
MOZ_ASSERT(workerPrivate);

dom/serviceworkers/ServiceWorkerScriptCache.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "js/Array.h" // JS::GetArrayLength
1010
#include "js/PropertyAndElement.h" // JS_GetElement
11+
#include "mozilla/TaskQueue.h"
1112
#include "mozilla/Unused.h"
1213
#include "mozilla/dom/CacheBinding.h"
1314
#include "mozilla/dom/cache/CacheStorage.h"
@@ -1278,7 +1279,9 @@ void CompareCache::ManageValueResult(JSContext* aCx,
12781279
if (rr) {
12791280
nsCOMPtr<nsIEventTarget> sts =
12801281
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
1281-
rv = rr->RetargetDeliveryTo(sts);
1282+
RefPtr<TaskQueue> queue =
1283+
TaskQueue::Create(sts.forget(), "CompareCache STS Delivery Queue");
1284+
rv = rr->RetargetDeliveryTo(queue);
12821285
if (NS_WARN_IF(NS_FAILED(rv))) {
12831286
mPump = nullptr;
12841287
Finish(rv, false);

dom/websocket/WebSocket.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class WebSocketImpl final : public nsIInterfaceRequestor,
111111
public nsIWebSocketListener,
112112
public nsIObserver,
113113
public nsIRequest,
114-
public nsIEventTarget,
114+
public nsISerialEventTarget,
115115
public nsIWebSocketImpl {
116116
public:
117117
NS_DECL_NSIINTERFACEREQUESTOR
@@ -255,7 +255,7 @@ class WebSocketImpl final : public nsIInterfaceRequestor,
255255
nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
256256

257257
// For dispatching runnables to main thread.
258-
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
258+
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
259259

260260
RefPtr<WebSocketImplProxy> mImplProxy;
261261

@@ -294,7 +294,8 @@ WebSocketImplProxy::SendMessage(const nsAString& aMessage) {
294294
}
295295

296296
NS_IMPL_ISUPPORTS(WebSocketImpl, nsIInterfaceRequestor, nsIWebSocketListener,
297-
nsIObserver, nsIRequest, nsIEventTarget, nsIWebSocketImpl)
297+
nsIObserver, nsIRequest, nsIEventTarget, nsISerialEventTarget,
298+
nsIWebSocketImpl)
298299

299300
class CallDispatchConnectionCloseEvents final : public DiscardableRunnable {
300301
public:
@@ -2826,6 +2827,8 @@ NS_IMETHODIMP_(bool)
28262827
WebSocketImpl::IsOnCurrentThreadInfallible() { return IsTargetThread(); }
28272828

28282829
bool WebSocketImpl::IsTargetThread() const {
2830+
// FIXME: This should also check if we're on the worker thread. Code using
2831+
// `IsOnCurrentThread` could easily misbehave here!
28292832
return NS_IsMainThread() == mIsMainThread;
28302833
}
28312834

dom/workers/WorkerPrivate.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3419,7 +3419,7 @@ void WorkerPrivate::AfterProcessNextEvent() {
34193419
MOZ_ASSERT(GetEffectiveEventLoopRecursionDepth());
34203420
}
34213421

3422-
nsIEventTarget* WorkerPrivate::MainThreadEventTargetForMessaging() {
3422+
nsISerialEventTarget* WorkerPrivate::MainThreadEventTargetForMessaging() {
34233423
return mMainThreadEventTargetForMessaging;
34243424
}
34253425

@@ -3435,7 +3435,7 @@ nsresult WorkerPrivate::DispatchToMainThreadForMessaging(
34353435
aFlags);
34363436
}
34373437

3438-
nsIEventTarget* WorkerPrivate::MainThreadEventTarget() {
3438+
nsISerialEventTarget* WorkerPrivate::MainThreadEventTarget() {
34393439
return mMainThreadEventTarget;
34403440
}
34413441

dom/workers/WorkerPrivate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ class WorkerPrivate final
560560
// Get the event target to use when dispatching to the main thread
561561
// from this Worker thread. This may be the main thread itself or
562562
// a ThrottledEventQueue to the main thread.
563-
nsIEventTarget* MainThreadEventTargetForMessaging();
563+
nsISerialEventTarget* MainThreadEventTargetForMessaging();
564564

565565
nsresult DispatchToMainThreadForMessaging(
566566
nsIRunnable* aRunnable, uint32_t aFlags = NS_DISPATCH_NORMAL);
@@ -569,7 +569,7 @@ class WorkerPrivate final
569569
already_AddRefed<nsIRunnable> aRunnable,
570570
uint32_t aFlags = NS_DISPATCH_NORMAL);
571571

572-
nsIEventTarget* MainThreadEventTarget();
572+
nsISerialEventTarget* MainThreadEventTarget();
573573

574574
nsresult DispatchToMainThread(nsIRunnable* aRunnable,
575575
uint32_t aFlags = NS_DISPATCH_NORMAL);

0 commit comments

Comments
 (0)