Commit 90e6ebd6 authored by smayya's avatar smayya
Browse files

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

parent f05fe128
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -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) {
+8 −0
Original line number Diff line number Diff line
@@ -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;