Bug 1938471 - synchronize access to FetchDriver::mObserver. r=necko-reviewers,kershaw, a=dmeehan

Differential Revision: https://phabricator.services.mozilla.com/D235762
This commit is contained in:
smayya 2025-02-04 15:48:43 +00:00
parent f05fe128f1
commit 90e6ebd641
2 changed files with 26 additions and 6 deletions

View file

@ -342,6 +342,7 @@ FetchDriver::FetchDriver(SafeRefPtr<InternalRequest> aRequest,
: mPrincipal(aPrincipal),
mLoadGroup(aLoadGroup),
mRequest(std::move(aRequest)),
mODAMutex("FetchDriver::mODAMutex"),
mMainThreadEventTarget(aMainThreadEventTarget),
mCookieJarSettings(aCookieJarSettings),
mPerformanceStorage(aPerformanceStorage),
@ -1384,7 +1385,10 @@ FetchDriver::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
uint64_t aOffset, uint32_t aCount) {
// NB: This can be called on any thread! But we're guaranteed that it is
// called between OnStartRequest and OnStopRequest, so we don't need to worry
// about races.
// about races for the members accessed in OnStartRequest, OnStopRequest,
// FailWithNetworkError and member functions accessed before opening the
// channel. However, we have a possibility of a race from
// FetchDriverAbortActions
if (!mPipeOutputStream) {
// We ignore the body for HEAD/CONNECT requests.
@ -1398,9 +1402,13 @@ FetchDriver::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
if (mNeedToObserveOnDataAvailable) {
mNeedToObserveOnDataAvailable = false;
if (mObserver) {
RefPtr<FetchDriverObserver> observer;
{
MutexAutoLock lock(mODAMutex);
// Need to keep mObserver alive.
RefPtr<FetchDriverObserver> observer = mObserver;
observer = mObserver;
}
if (observer) {
if (NS_IsMainThread()) {
observer->OnDataAvailable();
} else {
@ -1796,8 +1804,13 @@ void FetchDriver::RunAbortAlgorithm() { FetchDriverAbortActions(Signal()); }
void FetchDriver::FetchDriverAbortActions(AbortSignalImpl* aSignalImpl) {
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
RefPtr<FetchDriverObserver> observer;
{
MutexAutoLock lock(mODAMutex);
observer = std::move(mObserver);
}
if (mObserver) {
if (observer) {
#ifdef DEBUG
mResponseAvailableCalled = true;
#endif
@ -1805,8 +1818,7 @@ void FetchDriver::FetchDriverAbortActions(AbortSignalImpl* aSignalImpl) {
if (aSignalImpl) {
reason.set(aSignalImpl->RawReason());
}
mObserver->OnResponseEnd(FetchDriverObserver::eAborted, reason);
mObserver = nullptr;
observer->OnResponseEnd(FetchDriverObserver::eAborted, reason);
}
if (mChannel) {

View file

@ -18,6 +18,7 @@
#include "mozilla/dom/SerializedStackHolder.h"
#include "mozilla/dom/SRIMetadata.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Mutex.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/DebugOnly.h"
@ -155,6 +156,13 @@ class FetchDriver final : public nsIChannelEventSink,
SafeRefPtr<InternalRequest> mRequest;
SafeRefPtr<InternalResponse> mResponse;
nsCOMPtr<nsIOutputStream> mPipeOutputStream;
// mutex to prevent race between OnDataAvailable (OMT) and main thread
// functions
Mutex mODAMutex;
// access to mObserver can race between FetchDriverAbortActions (main thread)
// and OnDataAvailable (OMT)
// See Bug 1810805
RefPtr<FetchDriverObserver> mObserver;
RefPtr<Document> mDocument;
nsCOMPtr<nsICSPEventListener> mCSPEventListener;