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
This commit is contained in:
Nika Layzell
2023-06-07 14:48:38 +00:00
parent 52c1f68b43
commit a51fa32bd1
41 changed files with 133 additions and 112 deletions

View File

@@ -23,6 +23,7 @@
#include "mozilla/dom/WorkerScope.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/TaskQueue.h"
#include "nsComponentManagerUtils.h"
#include "nsIFile.h"
#include "nsIThreadRetargetableRequest.h"
@@ -272,7 +273,7 @@ NS_IMPL_ISUPPORTS(ConsumeBodyDoneObserver, nsIStreamLoaderObserver)
} // namespace
/* static */ already_AddRefed<Promise> BodyConsumer::Create(
nsIGlobalObject* aGlobal, nsIEventTarget* aMainThreadEventTarget,
nsIGlobalObject* aGlobal, nsISerialEventTarget* aMainThreadEventTarget,
nsIInputStream* aBodyStream, AbortSignalImpl* aSignalImpl,
ConsumeType aType, const nsACString& aBodyBlobURISpec,
const nsAString& aBodyLocalPath, const nsACString& aBodyMimeType,
@@ -359,10 +360,11 @@ void BodyConsumer::ReleaseObject() {
}
BodyConsumer::BodyConsumer(
nsIEventTarget* aMainThreadEventTarget, nsIGlobalObject* aGlobalObject,
nsIInputStream* aBodyStream, Promise* aPromise, ConsumeType aType,
const nsACString& aBodyBlobURISpec, const nsAString& aBodyLocalPath,
const nsACString& aBodyMimeType, const nsACString& aMixedCaseMimeType,
nsISerialEventTarget* aMainThreadEventTarget,
nsIGlobalObject* aGlobalObject, nsIInputStream* aBodyStream,
Promise* aPromise, ConsumeType aType, const nsACString& aBodyBlobURISpec,
const nsAString& aBodyLocalPath, const nsACString& aBodyMimeType,
const nsACString& aMixedCaseMimeType,
MutableBlobStorage::MutableBlobStorageType aBlobStorageType)
: mTargetThread(NS_GetCurrentThread()),
mMainThreadEventTarget(aMainThreadEventTarget),
@@ -575,7 +577,9 @@ void BodyConsumer::BeginConsumeBodyMainThread(ThreadSafeWorkerRef* aWorkerRef) {
if (rr) {
nsCOMPtr<nsIEventTarget> sts =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
rv = rr->RetargetDeliveryTo(sts);
RefPtr<TaskQueue> queue =
TaskQueue::Create(sts.forget(), "BodyConsumer STS Delivery Queue");
rv = rr->RetargetDeliveryTo(queue);
if (NS_FAILED(rv)) {
NS_WARNING("Retargeting failed");
}

View File

@@ -60,7 +60,7 @@ class BodyConsumer final : public nsIObserver,
* @param aRv An ErrorResult.
*/
static already_AddRefed<Promise> Create(
nsIGlobalObject* aGlobal, nsIEventTarget* aMainThreadEventTarget,
nsIGlobalObject* aGlobal, nsISerialEventTarget* aMainThreadEventTarget,
nsIInputStream* aBodyStream, AbortSignalImpl* aSignalImpl,
ConsumeType aType, const nsACString& aBodyBlobURISpec,
const nsAString& aBodyLocalPath, const nsACString& aBodyMimeType,
@@ -94,7 +94,7 @@ class BodyConsumer final : public nsIObserver,
void RunAbortAlgorithm() override;
private:
BodyConsumer(nsIEventTarget* aMainThreadEventTarget,
BodyConsumer(nsISerialEventTarget* aMainThreadEventTarget,
nsIGlobalObject* aGlobalObject, nsIInputStream* aBodyStream,
Promise* aPromise, ConsumeType aType,
const nsACString& aBodyBlobURISpec,
@@ -109,7 +109,7 @@ class BodyConsumer final : public nsIObserver,
void AssertIsOnTargetThread() const;
nsCOMPtr<nsIThread> mTargetThread;
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
// This is nullified when the consuming of the body starts.
nsCOMPtr<nsIInputStream> mBodyStream;

View File

@@ -76,7 +76,7 @@ class EventSourceImpl final : public nsIObserver,
public nsIChannelEventSink,
public nsIInterfaceRequestor,
public nsSupportsWeakReference,
public nsIEventTarget,
public nsISerialEventTarget,
public nsITimerCallback,
public nsINamed,
public nsIThreadRetargetableStreamListener {
@@ -364,8 +364,9 @@ class EventSourceImpl final : public nsIObserver,
NS_IMPL_ISUPPORTS(EventSourceImpl, nsIObserver, nsIStreamListener,
nsIRequestObserver, nsIChannelEventSink,
nsIInterfaceRequestor, nsISupportsWeakReference,
nsIEventTarget, nsIThreadRetargetableStreamListener,
nsITimerCallback, nsINamed)
nsISerialEventTarget, nsIEventTarget,
nsIThreadRetargetableStreamListener, nsITimerCallback,
nsINamed)
EventSourceImpl::EventSourceImpl(EventSource* aEventSource,
nsICookieJarSettings* aCookieJarSettings)
@@ -1056,16 +1057,15 @@ nsresult EventSourceImpl::InitChannelAndRequestEventSource(
MOZ_ASSERT_IF(mIsMainThread, aEventTargetAccessAllowed);
nsresult rv = aEventTargetAccessAllowed
? [this]() {
// We can't call GetEventSource() because we're not
// allowed to touch the refcount off the worker thread
// due to an assertion, event if it would have otherwise
// been safe.
auto lock = mSharedData.Lock();
return lock->mEventSource->CheckCurrentGlobalCorrectness();
}()
: NS_OK;
nsresult rv = aEventTargetAccessAllowed ? [this]() {
// We can't call GetEventSource() because we're not
// allowed to touch the refcount off the worker thread
// due to an assertion, event if it would have otherwise
// been safe.
auto lock = mSharedData.Lock();
return lock->mEventSource->CheckCurrentGlobalCorrectness();
}()
: NS_OK;
if (NS_FAILED(rv) || !isValidScheme) {
DispatchFailConnection();
return NS_ERROR_DOM_SECURITY_ERR;

View File

@@ -251,7 +251,7 @@ class FetchBody : public FetchBodyBase, public AbortFollower {
bool mBodyUsed;
// The main-thread event target for runnable dispatching.
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
};
class EmptyBody final : public FetchBody<EmptyBody> {

View File

@@ -6,6 +6,7 @@
#include "js/Value.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/TaskQueue.h"
#include "mozilla/dom/FetchDriver.h"
#include "mozilla/dom/ReferrerInfo.h"
@@ -1236,7 +1237,9 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest) {
// Try to retarget off main thread.
if (nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(aRequest)) {
Unused << NS_WARN_IF(NS_FAILED(rr->RetargetDeliveryTo(sts)));
RefPtr<TaskQueue> queue =
TaskQueue::Create(sts.forget(), "FetchDriver STS Delivery Queue");
Unused << NS_WARN_IF(NS_FAILED(rr->RetargetDeliveryTo(queue)));
}
return NS_OK;
}

View File

@@ -274,7 +274,7 @@ already_AddRefed<Promise> Blob::ConsumeBody(
return nullptr;
}
nsCOMPtr<nsIEventTarget> mainThreadEventTarget;
nsCOMPtr<nsISerialEventTarget> mainThreadEventTarget;
if (!NS_IsMainThread()) {
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);

View File

@@ -8,6 +8,7 @@
#include "js/Array.h" // JS::GetArrayLength
#include "js/PropertyAndElement.h" // JS_GetElement
#include "mozilla/TaskQueue.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/CacheBinding.h"
#include "mozilla/dom/cache/CacheStorage.h"
@@ -1278,7 +1279,9 @@ void CompareCache::ManageValueResult(JSContext* aCx,
if (rr) {
nsCOMPtr<nsIEventTarget> sts =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
rv = rr->RetargetDeliveryTo(sts);
RefPtr<TaskQueue> queue =
TaskQueue::Create(sts.forget(), "CompareCache STS Delivery Queue");
rv = rr->RetargetDeliveryTo(queue);
if (NS_WARN_IF(NS_FAILED(rv))) {
mPump = nullptr;
Finish(rv, false);

View File

@@ -111,7 +111,7 @@ class WebSocketImpl final : public nsIInterfaceRequestor,
public nsIWebSocketListener,
public nsIObserver,
public nsIRequest,
public nsIEventTarget,
public nsISerialEventTarget,
public nsIWebSocketImpl {
public:
NS_DECL_NSIINTERFACEREQUESTOR
@@ -255,7 +255,7 @@ class WebSocketImpl final : public nsIInterfaceRequestor,
nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
// For dispatching runnables to main thread.
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
RefPtr<WebSocketImplProxy> mImplProxy;
@@ -294,7 +294,8 @@ WebSocketImplProxy::SendMessage(const nsAString& aMessage) {
}
NS_IMPL_ISUPPORTS(WebSocketImpl, nsIInterfaceRequestor, nsIWebSocketListener,
nsIObserver, nsIRequest, nsIEventTarget, nsIWebSocketImpl)
nsIObserver, nsIRequest, nsIEventTarget, nsISerialEventTarget,
nsIWebSocketImpl)
class CallDispatchConnectionCloseEvents final : public DiscardableRunnable {
public:
@@ -2826,6 +2827,8 @@ NS_IMETHODIMP_(bool)
WebSocketImpl::IsOnCurrentThreadInfallible() { return IsTargetThread(); }
bool WebSocketImpl::IsTargetThread() const {
// FIXME: This should also check if we're on the worker thread. Code using
// `IsOnCurrentThread` could easily misbehave here!
return NS_IsMainThread() == mIsMainThread;
}

View File

@@ -3419,7 +3419,7 @@ void WorkerPrivate::AfterProcessNextEvent() {
MOZ_ASSERT(GetEffectiveEventLoopRecursionDepth());
}
nsIEventTarget* WorkerPrivate::MainThreadEventTargetForMessaging() {
nsISerialEventTarget* WorkerPrivate::MainThreadEventTargetForMessaging() {
return mMainThreadEventTargetForMessaging;
}
@@ -3435,7 +3435,7 @@ nsresult WorkerPrivate::DispatchToMainThreadForMessaging(
aFlags);
}
nsIEventTarget* WorkerPrivate::MainThreadEventTarget() {
nsISerialEventTarget* WorkerPrivate::MainThreadEventTarget() {
return mMainThreadEventTarget;
}

View File

@@ -560,7 +560,7 @@ class WorkerPrivate final
// Get the event target to use when dispatching to the main thread
// from this Worker thread. This may be the main thread itself or
// a ThrottledEventQueue to the main thread.
nsIEventTarget* MainThreadEventTargetForMessaging();
nsISerialEventTarget* MainThreadEventTargetForMessaging();
nsresult DispatchToMainThreadForMessaging(
nsIRunnable* aRunnable, uint32_t aFlags = NS_DISPATCH_NORMAL);
@@ -569,7 +569,7 @@ class WorkerPrivate final
already_AddRefed<nsIRunnable> aRunnable,
uint32_t aFlags = NS_DISPATCH_NORMAL);
nsIEventTarget* MainThreadEventTarget();
nsISerialEventTarget* MainThreadEventTarget();
nsresult DispatchToMainThread(nsIRunnable* aRunnable,
uint32_t aFlags = NS_DISPATCH_NORMAL);

View File

@@ -23,6 +23,7 @@
#include "mozilla/dom/Response.h"
#include "mozilla/dom/ServiceWorkerBinding.h" // ServiceWorkerState
#include "mozilla/Result.h"
#include "mozilla/TaskQueue.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/WorkerScope.h"
@@ -477,7 +478,9 @@ void CacheLoadHandler::ResolvedCallback(JSContext* aCx,
if (rr) {
nsCOMPtr<nsIEventTarget> sts =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
rv = rr->RetargetDeliveryTo(sts);
RefPtr<TaskQueue> queue =
TaskQueue::Create(sts.forget(), "CacheLoadHandler STS Delivery Queue");
rv = rr->RetargetDeliveryTo(queue);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to dispatch the nsIInputStreamPump to a IO thread.");
}

View File

@@ -119,7 +119,7 @@ class CacheLoadHandler final : public PromiseNativeHandler,
nsCString mCSPHeaderValue;
nsCString mCSPReportOnlyHeaderValue;
nsCString mReferrerPolicyHeaderValue;
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
};
/*

View File

@@ -21,6 +21,7 @@
#include "mozilla/dom/worklet/WorkletModuleLoader.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/TaskQueue.h"
#include "nsIInputStreamPump.h"
#include "nsIThreadRetargetableRequest.h"
@@ -573,7 +574,9 @@ void WorkletScriptHandler::ResolvedCallback(JSContext* aCx,
if (rr) {
nsCOMPtr<nsIEventTarget> sts =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
rv = rr->RetargetDeliveryTo(sts);
RefPtr<TaskQueue> queue = TaskQueue::Create(
sts.forget(), "WorkletScriptHandler STS Delivery Queue");
rv = rr->RetargetDeliveryTo(queue);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to dispatch the nsIInputStreamPump to a IO thread.");
}

View File

@@ -193,9 +193,9 @@ void DecodePool::SyncRunIfPossible(IDecodingTask* aTask,
aTask->Run();
}
already_AddRefed<nsIEventTarget> DecodePool::GetIOEventTarget() {
already_AddRefed<nsISerialEventTarget> DecodePool::GetIOEventTarget() {
MutexAutoLock threadPoolLock(mMutex);
nsCOMPtr<nsIEventTarget> target = mIOThread;
nsCOMPtr<nsISerialEventTarget> target = mIOThread;
return target.forget();
}

View File

@@ -83,9 +83,9 @@ class DecodePool final : public nsIObserver {
* who want to deliver data to workers on the DecodePool can use this event
* target.
*
* @return An nsIEventTarget interface to the thread pool's I/O thread.
* @return An nsISerialEventTarget interface to the thread pool's I/O thread.
*/
already_AddRefed<nsIEventTarget> GetIOEventTarget();
already_AddRefed<nsISerialEventTarget> GetIOEventTarget();
private:
friend class DecodePoolWorker;

View File

@@ -217,7 +217,7 @@ nsIconChannel::AsyncOpen(nsIStreamListener* aListener) {
}
// Init our stream pump
nsCOMPtr<nsIEventTarget> target =
nsCOMPtr<nsISerialEventTarget> target =
nsContentUtils::GetEventTargetByLoadInfo(mLoadInfo, mozilla::TaskCategory::Other);
rv = mPump->Init(inStream, 0, 0, false, target);
if (NS_FAILED(rv)) {

View File

@@ -843,7 +843,7 @@ nsresult nsIconChannel::StartAsyncOpen() {
// Use the main thread for the pumped events unless the load info
// specifies otherwise
nsCOMPtr<nsIEventTarget> listenerTarget =
nsCOMPtr<nsISerialEventTarget> listenerTarget =
nsContentUtils::GetEventTargetByLoadInfo(mLoadInfo,
mozilla::TaskCategory::Other);
if (!listenerTarget) {

View File

@@ -711,7 +711,7 @@ imgRequest::OnStartRequest(nsIRequest* aRequest) {
nsresult rv = channel->GetContentType(mimeType);
if (NS_SUCCEEDED(rv) && !mimeType.EqualsLiteral(IMAGE_SVG_XML)) {
// Retarget OnDataAvailable to the DecodePool's IO thread.
nsCOMPtr<nsIEventTarget> target =
nsCOMPtr<nsISerialEventTarget> target =
DecodePool::Singleton()->GetIOEventTarget();
rv = retargetable->RetargetDeliveryTo(target);
}

View File

@@ -15,6 +15,7 @@
#include "mozilla/AutoRestore.h"
#include "mozilla/Preferences.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/TaskQueue.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Unused.h"
#include "FontFaceSet.h"
@@ -340,7 +341,9 @@ nsFontFaceLoader::OnStartRequest(nsIRequest* aRequest) {
if (req) {
nsCOMPtr<nsIEventTarget> sts =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
Unused << NS_WARN_IF(NS_FAILED(req->RetargetDeliveryTo(sts)));
RefPtr<TaskQueue> queue =
TaskQueue::Create(sts.forget(), "nsFontFaceLoader STS Delivery Queue");
Unused << NS_WARN_IF(NS_FAILED(req->RetargetDeliveryTo(queue)));
}
return NS_OK;
}

View File

@@ -1324,7 +1324,7 @@ nsJARChannel::OnDataAvailable(nsIRequest* req, nsIInputStream* stream,
}
NS_IMETHODIMP
nsJARChannel::RetargetDeliveryTo(nsIEventTarget* aEventTarget) {
nsJARChannel::RetargetDeliveryTo(nsISerialEventTarget* aEventTarget) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIThreadRetargetableRequest> request = do_QueryInterface(mRequest);
@@ -1336,7 +1336,7 @@ nsJARChannel::RetargetDeliveryTo(nsIEventTarget* aEventTarget) {
}
NS_IMETHODIMP
nsJARChannel::GetDeliveryTarget(nsIEventTarget** aEventTarget) {
nsJARChannel::GetDeliveryTarget(nsISerialEventTarget** aEventTarget) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIThreadRetargetableRequest> request = do_QueryInterface(mRequest);

View File

@@ -488,7 +488,7 @@ nsresult ProxyAutoConfig::ConfigurePAC(const nsACString& aPACURI,
const nsACString& aPACScriptData,
bool aIncludePath,
uint32_t aExtraHeapSize,
nsIEventTarget* aEventTarget) {
nsISerialEventTarget* aEventTarget) {
mShutdown = false; // Shutdown needs to be called prior to destruction
mPACURI = aPACURI;
@@ -904,7 +904,7 @@ nsresult RemoteProxyAutoConfig::ConfigurePAC(const nsACString& aPACURI,
const nsACString& aPACScriptData,
bool aIncludePath,
uint32_t aExtraHeapSize,
nsIEventTarget*) {
nsISerialEventTarget*) {
Unused << mProxyAutoConfigParent->SendConfigurePAC(
aPACURI, aPACScriptData, aIncludePath, aExtraHeapSize);
return NS_OK;

View File

@@ -33,7 +33,7 @@ class ProxyAutoConfigBase {
virtual nsresult ConfigurePAC(const nsACString& aPACURI,
const nsACString& aPACScriptData,
bool aIncludePath, uint32_t aExtraHeapSize,
nsIEventTarget* aEventTarget) = 0;
nsISerialEventTarget* aEventTarget) = 0;
virtual void SetThreadLocalIndex(uint32_t index) {}
virtual void Shutdown() = 0;
virtual void GC() = 0;
@@ -55,7 +55,7 @@ class ProxyAutoConfig : public ProxyAutoConfigBase {
nsresult ConfigurePAC(const nsACString& aPACURI,
const nsACString& aPACScriptData, bool aIncludePath,
uint32_t aExtraHeapSize,
nsIEventTarget* aEventTarget) override;
nsISerialEventTarget* aEventTarget) override;
void SetThreadLocalIndex(uint32_t index) override;
void Shutdown() override;
void GC() override;
@@ -125,7 +125,7 @@ class ProxyAutoConfig : public ProxyAutoConfigBase {
uint32_t mExtraHeapSize{0};
nsCString mRunningHost;
nsCOMPtr<nsITimer> mTimer;
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
};
class RemoteProxyAutoConfig : public ProxyAutoConfigBase {
@@ -137,7 +137,7 @@ class RemoteProxyAutoConfig : public ProxyAutoConfigBase {
nsresult ConfigurePAC(const nsACString& aPACURI,
const nsACString& aPACScriptData, bool aIncludePath,
uint32_t aExtraHeapSize,
nsIEventTarget* aEventTarget) override;
nsISerialEventTarget* aEventTarget) override;
void Shutdown() override;
void GC() override;
void GetProxyForURIWithCallback(

View File

@@ -203,7 +203,7 @@ nsresult nsBaseChannel::BeginPumpingData() {
// and especially when we call into the loadgroup. Our caller takes care to
// release mPump if we return an error.
nsCOMPtr<nsIEventTarget> target = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> target = GetNeckoTarget();
rv = nsInputStreamPump::Create(getter_AddRefs(mPump), stream, 0, 0, true,
target);
if (NS_FAILED(rv)) {
@@ -227,11 +227,9 @@ nsresult nsBaseChannel::BeginPumpingData() {
mPump->Suspend();
RefPtr<nsBaseChannel> self(this);
nsCOMPtr<nsISerialEventTarget> serialTarget(do_QueryInterface(target));
MOZ_ASSERT(serialTarget);
promise->Then(
serialTarget, __func__,
target, __func__,
[self, this](nsresult rv) {
MOZ_ASSERT(mPump);
MOZ_ASSERT(NS_SUCCEEDED(rv));
@@ -897,7 +895,7 @@ nsBaseChannel::OnRedirectVerifyCallback(nsresult result) {
}
NS_IMETHODIMP
nsBaseChannel::RetargetDeliveryTo(nsIEventTarget* aEventTarget) {
nsBaseChannel::RetargetDeliveryTo(nsISerialEventTarget* aEventTarget) {
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE(mRequest, NS_ERROR_NOT_INITIALIZED);
@@ -913,7 +911,7 @@ nsBaseChannel::RetargetDeliveryTo(nsIEventTarget* aEventTarget) {
}
NS_IMETHODIMP
nsBaseChannel::GetDeliveryTarget(nsIEventTarget** aEventTarget) {
nsBaseChannel::GetDeliveryTarget(nsISerialEventTarget** aEventTarget) {
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE(mRequest, NS_ERROR_NOT_INITIALIZED);

View File

@@ -4,8 +4,8 @@
#include "nsIRequest.idl"
interface nsIEventTarget;
interface nsIInputStream;
interface nsISerialEventTarget;
interface nsIStreamListener;
/**
@@ -51,7 +51,7 @@ interface nsIInputStreamPump : nsIRequest
in unsigned long aSegmentSize,
in unsigned long aSegmentCount,
in boolean aCloseWhenDone,
[optional] in nsIEventTarget aMainThreadTarget);
[optional] in nsISerialEventTarget aMainThreadTarget);
/**
* asyncRead causes the input stream to be read in chunks and delivered

View File

@@ -6,7 +6,7 @@
#include "nsISupports.idl"
interface nsIEventTarget;
interface nsISerialEventTarget;
/**
* nsIThreadRetargetableRequest
@@ -31,7 +31,7 @@ interface nsIThreadRetargetableRequest : nsISupports
* should be ready to deal with OnDataAvailable on either the main thread or
* the new target thread.
*/
void retargetDeliveryTo(in nsIEventTarget aNewTarget);
void retargetDeliveryTo(in nsISerialEventTarget aNewTarget);
/**
* Returns the event target where OnDataAvailable events will be dispatched.
@@ -39,5 +39,5 @@ interface nsIThreadRetargetableRequest : nsISupports
* This is only valid after OnStartRequest has been called. Any time before
* that point, the value may be changed by `retargetDeliveryTo` calls.
*/
readonly attribute nsIEventTarget deliveryTarget;
readonly attribute nsISerialEventTarget deliveryTarget;
};

View File

@@ -37,7 +37,7 @@ nsInputStreamPump::nsInputStreamPump() : mOffMainThread(!NS_IsMainThread()) {}
nsresult nsInputStreamPump::Create(nsInputStreamPump** result,
nsIInputStream* stream, uint32_t segsize,
uint32_t segcount, bool closeWhenDone,
nsIEventTarget* mainThreadTarget) {
nsISerialEventTarget* mainThreadTarget) {
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
RefPtr<nsInputStreamPump> pump = new nsInputStreamPump();
if (pump) {
@@ -99,7 +99,7 @@ nsresult nsInputStreamPump::EnsureWaiting() {
// Ensure OnStateStop is called on the main thread only when this pump is
// created on main thread.
if (mState == STATE_STOP && !mOffMainThread) {
nsCOMPtr<nsIEventTarget> mainThread =
nsCOMPtr<nsISerialEventTarget> mainThread =
mLabeledMainThreadTarget
? mLabeledMainThreadTarget
: do_AddRef(mozilla::GetMainThreadSerialEventTarget());
@@ -306,7 +306,7 @@ nsInputStreamPump::SetLoadGroup(nsILoadGroup* aLoadGroup) {
NS_IMETHODIMP
nsInputStreamPump::Init(nsIInputStream* stream, uint32_t segsize,
uint32_t segcount, bool closeWhenDone,
nsIEventTarget* mainThreadTarget) {
nsISerialEventTarget* mainThreadTarget) {
// probably we can't be multithread-accessed yet
RecursiveMutexAutoLock lock(mMutex);
NS_ENSURE_TRUE(mState == STATE_IDLE, NS_ERROR_IN_PROGRESS);
@@ -733,7 +733,7 @@ nsresult nsInputStreamPump::CreateBufferedStreamIfNeeded() {
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsInputStreamPump::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
nsInputStreamPump::RetargetDeliveryTo(nsISerialEventTarget* aNewTarget) {
RecursiveMutexAutoLock lock(mMutex);
NS_ENSURE_ARG(aNewTarget);
@@ -777,10 +777,10 @@ nsInputStreamPump::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
}
NS_IMETHODIMP
nsInputStreamPump::GetDeliveryTarget(nsIEventTarget** aNewTarget) {
nsInputStreamPump::GetDeliveryTarget(nsISerialEventTarget** aNewTarget) {
RecursiveMutexAutoLock lock(mMutex);
nsCOMPtr<nsIEventTarget> target = mTargetThread;
nsCOMPtr<nsISerialEventTarget> target = mTargetThread;
target.forget(aNewTarget);
return NS_OK;
}

View File

@@ -15,7 +15,7 @@
#ifdef DEBUG
# include "MainThreadUtils.h"
# include "nsIEventTarget.h"
# include "nsISerialEventTarget.h"
#endif
class nsIInputStream;
@@ -49,7 +49,7 @@ class nsInputStreamPump final : public nsIInputStreamPump,
static nsresult Create(nsInputStreamPump** result, nsIInputStream* stream,
uint32_t segsize = 0, uint32_t segcount = 0,
bool closeWhenDone = false,
nsIEventTarget* mainThreadTarget = nullptr);
nsISerialEventTarget* mainThreadTarget = nullptr);
using PeekSegmentFun = void (*)(void*, const uint8_t*, uint32_t);
/**
@@ -94,8 +94,9 @@ class nsInputStreamPump final : public nsIInputStreamPump,
// off-MainThread thread), read from that thread and perhaps others (in
// RetargetDeliveryTo)
nsCOMPtr<nsIStreamListener> mListener MOZ_GUARDED_BY(mMutex);
nsCOMPtr<nsIEventTarget> mTargetThread MOZ_GUARDED_BY(mMutex);
nsCOMPtr<nsIEventTarget> mLabeledMainThreadTarget MOZ_GUARDED_BY(mMutex);
nsCOMPtr<nsISerialEventTarget> mTargetThread MOZ_GUARDED_BY(mMutex);
nsCOMPtr<nsISerialEventTarget> mLabeledMainThreadTarget
MOZ_GUARDED_BY(mMutex);
nsCOMPtr<nsIInputStream> mStream MOZ_GUARDED_BY(mMutex);
// mAsyncStream is written on a single thread (either MainThread or an
// off-MainThread thread), and lives from AsyncRead() to OnStateStop().

View File

@@ -857,7 +857,7 @@ nsresult NS_NewInputStreamPump(
nsIInputStreamPump** aResult, already_AddRefed<nsIInputStream> aStream,
uint32_t aSegsize /* = 0 */, uint32_t aSegcount /* = 0 */,
bool aCloseWhenDone /* = false */,
nsIEventTarget* aMainThreadTarget /* = nullptr */) {
nsISerialEventTarget* aMainThreadTarget /* = nullptr */) {
nsCOMPtr<nsIInputStream> stream = std::move(aStream);
nsresult rv;

View File

@@ -51,6 +51,7 @@ class nsIPersistentProperties;
class nsIProxyInfo;
class nsIRandomAccessStream;
class nsIRequestObserver;
class nsISerialEventTarget;
class nsIStreamListener;
class nsIStreamLoader;
class nsIStreamLoaderObserver;
@@ -346,11 +347,10 @@ nsresult NS_NewInputStreamChannel(nsIChannel** outChannel, nsIURI* aUri,
nsContentPolicyType aContentPolicyType,
bool aIsSrcdocChannel = false);
nsresult NS_NewInputStreamPump(nsIInputStreamPump** aResult,
already_AddRefed<nsIInputStream> aStream,
uint32_t aSegsize = 0, uint32_t aSegcount = 0,
bool aCloseWhenDone = false,
nsIEventTarget* aMainThreadTarget = nullptr);
nsresult NS_NewInputStreamPump(
nsIInputStreamPump** aResult, already_AddRefed<nsIInputStream> aStream,
uint32_t aSegsize = 0, uint32_t aSegcount = 0, bool aCloseWhenDone = false,
nsISerialEventTarget* aMainThreadTarget = nullptr);
nsresult NS_NewLoadGroup(nsILoadGroup** result, nsIRequestObserver* obs);

View File

@@ -271,7 +271,7 @@ class ExecutePACThreadAction final : public Runnable {
if (mSetupPAC) {
mSetupPAC = false;
nsCOMPtr<nsIEventTarget> target = mPACMan->GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> target = mPACMan->GetNeckoTarget();
mPACMan->mPAC->ConfigurePAC(mSetupPACURI, mSetupPACData,
mPACMan->mIncludePath, mExtraHeapSize,
target);

View File

@@ -2813,7 +2813,7 @@ HttpChannelChild::GetIsLastPart(bool* aIsLastPart) {
//-----------------------------------------------------------------------------
NS_IMETHODIMP
HttpChannelChild::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
HttpChannelChild::RetargetDeliveryTo(nsISerialEventTarget* aNewTarget) {
LOG(("HttpChannelChild::RetargetDeliveryTo [this=%p, aNewTarget=%p]", this,
aNewTarget));
@@ -2864,10 +2864,10 @@ HttpChannelChild::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
}
NS_IMETHODIMP
HttpChannelChild::GetDeliveryTarget(nsIEventTarget** aEventTarget) {
HttpChannelChild::GetDeliveryTarget(nsISerialEventTarget** aEventTarget) {
MutexAutoLock lock(mEventTargetMutex);
nsCOMPtr<nsIEventTarget> target = mODATarget;
nsCOMPtr<nsISerialEventTarget> target = mODATarget;
if (!mODATarget) {
target = GetCurrentSerialEventTarget();
}

View File

@@ -298,7 +298,7 @@ class HttpChannelChild final : public PHttpChannelChild,
void CleanupBackgroundChannel();
// Target thread for delivering ODA.
nsCOMPtr<nsIEventTarget> mODATarget MOZ_GUARDED_BY(mEventTargetMutex);
nsCOMPtr<nsISerialEventTarget> mODATarget MOZ_GUARDED_BY(mEventTargetMutex);
// Used to ensure atomicity of mNeckoTarget / mODATarget;
Mutex mEventTargetMutex{"HttpChannelChild::EventTargetMutex"};

View File

@@ -200,10 +200,10 @@ void HttpTransactionParent::SetSniffedTypeToChannel(
}
NS_IMETHODIMP
HttpTransactionParent::GetDeliveryTarget(nsIEventTarget** aEventTarget) {
HttpTransactionParent::GetDeliveryTarget(nsISerialEventTarget** aEventTarget) {
MutexAutoLock lock(mEventTargetMutex);
nsCOMPtr<nsIEventTarget> target = mODATarget;
nsCOMPtr<nsISerialEventTarget> target = mODATarget;
if (!mODATarget) {
target = mTargetThread;
}
@@ -211,8 +211,8 @@ HttpTransactionParent::GetDeliveryTarget(nsIEventTarget** aEventTarget) {
return NS_OK;
}
already_AddRefed<nsIEventTarget> HttpTransactionParent::GetODATarget() {
nsCOMPtr<nsIEventTarget> target;
already_AddRefed<nsISerialEventTarget> HttpTransactionParent::GetODATarget() {
nsCOMPtr<nsISerialEventTarget> target;
{
MutexAutoLock lock(mEventTargetMutex);
target = mODATarget ? mODATarget : mTargetThread;
@@ -225,7 +225,7 @@ already_AddRefed<nsIEventTarget> HttpTransactionParent::GetODATarget() {
}
NS_IMETHODIMP HttpTransactionParent::RetargetDeliveryTo(
nsIEventTarget* aEventTarget) {
nsISerialEventTarget* aEventTarget) {
LOG(("HttpTransactionParent::RetargetDeliveryTo [this=%p, aTarget=%p]", this,
aEventTarget));

View File

@@ -117,14 +117,14 @@ class HttpTransactionParent final : public PHttpTransactionParent,
void DoNotifyListener();
void ContinueDoNotifyListener();
// Get event target for ODA.
already_AddRefed<nsIEventTarget> GetODATarget();
already_AddRefed<nsISerialEventTarget> GetODATarget();
void CancelOnMainThread(nsresult aRv);
void HandleAsyncAbort();
nsCOMPtr<nsITransportEventSink> mEventsink;
nsCOMPtr<nsIStreamListener> mChannel;
nsCOMPtr<nsIEventTarget> mTargetThread;
nsCOMPtr<nsIEventTarget> mODATarget;
nsCOMPtr<nsISerialEventTarget> mTargetThread;
nsCOMPtr<nsISerialEventTarget> mODATarget;
Mutex mEventTargetMutex MOZ_UNANNOTATED{
"HttpTransactionParent::EventTargetMutex"};
nsCOMPtr<nsITransportSecurityInfo> mSecurityInfo;

View File

@@ -1196,7 +1196,7 @@ InterceptedHttpChannel::OnDataAvailable(nsIRequest* aRequest,
}
NS_IMETHODIMP
InterceptedHttpChannel::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
InterceptedHttpChannel::RetargetDeliveryTo(nsISerialEventTarget* aNewTarget) {
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_ARG(aNewTarget);
@@ -1215,7 +1215,7 @@ InterceptedHttpChannel::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
}
NS_IMETHODIMP
InterceptedHttpChannel::GetDeliveryTarget(nsIEventTarget** aEventTarget) {
InterceptedHttpChannel::GetDeliveryTarget(nsISerialEventTarget** aEventTarget) {
if (!mPump) {
return NS_ERROR_NOT_AVAILABLE;
}

View File

@@ -8148,7 +8148,7 @@ nsHttpChannel::OnDataAvailable(nsIRequest* request, nsIInputStream* input,
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsHttpChannel::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
nsHttpChannel::RetargetDeliveryTo(nsISerialEventTarget* aNewTarget) {
MOZ_ASSERT(NS_IsMainThread(), "Should be called on main thread only");
NS_ENSURE_ARG(aNewTarget);
@@ -8181,7 +8181,7 @@ nsHttpChannel::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
// If retarget fails for transaction pump, we must restore mCachePump.
if (NS_FAILED(rv) && retargetableCachePump) {
nsCOMPtr<nsIEventTarget> main = GetMainThreadSerialEventTarget();
nsCOMPtr<nsISerialEventTarget> main = GetMainThreadSerialEventTarget();
NS_ENSURE_TRUE(main, NS_ERROR_UNEXPECTED);
rv = retargetableCachePump->RetargetDeliveryTo(main);
}
@@ -8190,7 +8190,7 @@ nsHttpChannel::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
}
NS_IMETHODIMP
nsHttpChannel::GetDeliveryTarget(nsIEventTarget** aEventTarget) {
nsHttpChannel::GetDeliveryTarget(nsISerialEventTarget** aEventTarget) {
if (mCachePump) {
return mCachePump->GetDeliveryTarget(aEventTarget);
}

View File

@@ -68,7 +68,7 @@ BaseWebSocketChannel::~BaseWebSocketChannel() {
NS_ReleaseOnMainThread("BaseWebSocketChannel::mLoadGroup",
mLoadGroup.forget());
NS_ReleaseOnMainThread("BaseWebSocketChannel::mLoadInfo", mLoadInfo.forget());
nsCOMPtr<nsIEventTarget> target;
nsCOMPtr<nsISerialEventTarget> target;
{
auto lock = mTargetThread.Lock();
target.swap(*lock);
@@ -310,7 +310,7 @@ BaseWebSocketChannel::AllowPort(int32_t port, const char* scheme,
//-----------------------------------------------------------------------------
NS_IMETHODIMP
BaseWebSocketChannel::RetargetDeliveryTo(nsIEventTarget* aTargetThread) {
BaseWebSocketChannel::RetargetDeliveryTo(nsISerialEventTarget* aTargetThread) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aTargetThread);
MOZ_ASSERT(!mWasOpened, "Should not be called after AsyncOpen!");
@@ -324,10 +324,10 @@ BaseWebSocketChannel::RetargetDeliveryTo(nsIEventTarget* aTargetThread) {
}
NS_IMETHODIMP
BaseWebSocketChannel::GetDeliveryTarget(nsIEventTarget** aTargetThread) {
BaseWebSocketChannel::GetDeliveryTarget(nsISerialEventTarget** aTargetThread) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIEventTarget> target = GetTargetThread();
nsCOMPtr<nsISerialEventTarget> target = GetTargetThread();
if (!target) {
target = GetCurrentSerialEventTarget();
}
@@ -335,15 +335,15 @@ BaseWebSocketChannel::GetDeliveryTarget(nsIEventTarget** aTargetThread) {
return NS_OK;
}
already_AddRefed<nsIEventTarget> BaseWebSocketChannel::GetTargetThread() {
nsCOMPtr<nsIEventTarget> target;
already_AddRefed<nsISerialEventTarget> BaseWebSocketChannel::GetTargetThread() {
nsCOMPtr<nsISerialEventTarget> target;
auto lock = mTargetThread.Lock();
target = *lock;
return target.forget();
}
bool BaseWebSocketChannel::IsOnTargetThread() {
nsCOMPtr<nsIEventTarget> target = GetTargetThread();
nsCOMPtr<nsISerialEventTarget> target = GetTargetThread();
if (!target) {
MOZ_ASSERT(false);
return false;

View File

@@ -77,7 +77,7 @@ class BaseWebSocketChannel : public nsIWebSocketChannel,
virtual void GetEffectiveURL(nsAString& aEffectiveURL) const = 0;
virtual bool IsEncrypted() const = 0;
already_AddRefed<nsIEventTarget> GetTargetThread();
already_AddRefed<nsISerialEventTarget> GetTargetThread();
bool IsOnTargetThread();
class ListenerAndContextContainer final {
@@ -107,7 +107,7 @@ class BaseWebSocketChannel : public nsIWebSocketChannel,
// Used to ensure atomicity of mTargetThread.
// Set before AsyncOpen via RetargetDeliveryTo or in AsyncOpen, never changed
// after AsyncOpen
DataMutex<nsCOMPtr<nsIEventTarget>> mTargetThread{
DataMutex<nsCOMPtr<nsISerialEventTarget>> mTargetThread{
"BaseWebSocketChannel::EventTargetMutex"};
nsCString mProtocol;

View File

@@ -590,7 +590,7 @@ StreamFilterParent::OnStartRequest(nsIRequest* aRequest) {
// that we get the final delivery target after any retargeting that it may do.
if (nsCOMPtr<nsIThreadRetargetableRequest> req =
do_QueryInterface(aRequest)) {
nsCOMPtr<nsIEventTarget> thread;
nsCOMPtr<nsISerialEventTarget> thread;
Unused << req->GetDeliveryTarget(getter_AddRefs(thread));
if (thread) {
mIOThread = std::move(thread);
@@ -748,7 +748,7 @@ bool StreamFilterParent::IsActorThread() {
void StreamFilterParent::AssertIsActorThread() { MOZ_ASSERT(IsActorThread()); }
nsIEventTarget* StreamFilterParent::IOThread() { return mIOThread; }
nsISerialEventTarget* StreamFilterParent::IOThread() { return mIOThread; }
bool StreamFilterParent::IsIOThread() { return mIOThread->IsOnCurrentThread(); }

View File

@@ -137,7 +137,7 @@ class StreamFilterParent final : public PStreamFilterParent,
inline nsIEventTarget* ActorThread();
inline nsIEventTarget* IOThread();
inline nsISerialEventTarget* IOThread();
inline bool IsIOThread();
@@ -166,8 +166,8 @@ class StreamFilterParent final : public PStreamFilterParent,
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIStreamListener> mOrigListener;
nsCOMPtr<nsIEventTarget> mMainThread;
nsCOMPtr<nsIEventTarget> mIOThread;
nsCOMPtr<nsISerialEventTarget> mMainThread;
nsCOMPtr<nsISerialEventTarget> mIOThread;
RefPtr<net::ChannelEventQueue> mQueue;

View File

@@ -156,7 +156,7 @@ class faviconAsyncLoader : public AsyncStatementCallback, public nsICancelable {
nsresult rv;
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo();
nsCOMPtr<nsIEventTarget> target =
nsCOMPtr<nsISerialEventTarget> target =
nsContentUtils::GetEventTargetByLoadInfo(loadInfo, TaskCategory::Other);
if (!mData.IsEmpty()) {
nsCOMPtr<nsIInputStream> stream;