diff --git a/netwerk/base/nsDNSPrefetch.cpp b/netwerk/base/nsDNSPrefetch.cpp index 543eff032e17..ba4547741e24 100644 --- a/netwerk/base/nsDNSPrefetch.cpp +++ b/netwerk/base/nsDNSPrefetch.cpp @@ -54,8 +54,7 @@ nsDNSPrefetch::nsDNSPrefetch(nsIURI* aURI, : mOriginAttributes(aOriginAttributes), mStoreTiming(storeTiming), mTRRMode(aTRRMode), - mListener(aListener), - mTarget(GetCurrentThreadEventTarget()) { + mListener(do_GetWeakReference(aListener)) { aURI->GetAsciiHost(mHostname); mIsHttps = aURI->SchemeIs("https"); } @@ -72,11 +71,12 @@ nsresult nsDNSPrefetch::Prefetch(uint32_t flags) { // then our timing will be useless. However, in such a case, // mEndTimestamp will be a null timestamp and callers should check // TimingsValid() before using the timing. + nsCOMPtr target = mozilla::GetCurrentThreadEventTarget(); flags |= nsIDNSService::GetFlagsFromTRRMode(mTRRMode); nsresult rv = sDNSService->AsyncResolveNative( - mHostname, flags | nsIDNSService::RESOLVE_SPECULATE, this, mTarget, + mHostname, flags | nsIDNSService::RESOLVE_SPECULATE, this, target, mOriginAttributes, getter_AddRefs(tmpOutstanding)); if (NS_FAILED(rv)) { return rv; @@ -89,7 +89,7 @@ nsresult nsDNSPrefetch::Prefetch(uint32_t flags) { esniHost.Append(mHostname); sDNSService->AsyncResolveByTypeNative( esniHost, nsIDNSService::RESOLVE_TYPE_TXT, - flags | nsIDNSService::RESOLVE_SPECULATE, this, mTarget, + flags | nsIDNSService::RESOLVE_SPECULATE, this, target, mOriginAttributes, getter_AddRefs(tmpOutstanding)); } return NS_OK; @@ -114,16 +114,16 @@ NS_IMPL_ISUPPORTS(nsDNSPrefetch, nsIDNSListener) NS_IMETHODIMP nsDNSPrefetch::OnLookupComplete(nsICancelable* request, nsIDNSRecord* rec, nsresult status) { - MOZ_ASSERT(mTarget->IsOnCurrentThread()); - if (mStoreTiming) { mEndTimestamp = mozilla::TimeStamp::Now(); } - - nsCOMPtr listener; - mListener.swap(listener); - - MOZ_ASSERT(listener); - listener->OnLookupComplete(request, rec, status); + nsCOMPtr listener = do_QueryReferent(mListener); + if (listener) { + listener->OnLookupComplete(request, rec, status); + } + // OnLookupComplete should be called on the target thread, so we release + // mListener here to make sure mListener is also released on the target + // thread. + mListener = nullptr; return NS_OK; } diff --git a/netwerk/base/nsDNSPrefetch.h b/netwerk/base/nsDNSPrefetch.h index 697ea3e16053..1411721fa9d3 100644 --- a/netwerk/base/nsDNSPrefetch.h +++ b/netwerk/base/nsDNSPrefetch.h @@ -6,6 +6,7 @@ #ifndef nsDNSPrefetch_h___ #define nsDNSPrefetch_h___ +#include "nsIWeakReferenceUtils.h" #include "nsString.h" #include "mozilla/TimeStamp.h" #include "mozilla/Attributes.h" @@ -52,8 +53,7 @@ class nsDNSPrefetch final : public nsIDNSListener { nsIRequest::TRRMode mTRRMode; mozilla::TimeStamp mStartTimestamp; mozilla::TimeStamp mEndTimestamp; - nsCOMPtr mListener; - nsCOMPtr mTarget; + nsWeakPtr mListener; nsresult Prefetch(uint32_t flags); }; diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index a8504ac5d6e2..abcfe1a0d944 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -439,6 +439,7 @@ void nsHttpChannel::ReleaseMainThreadOnlyReferences() { arrayToRelease.AppendElement(mAuthProvider.forget()); arrayToRelease.AppendElement(mRedirectChannel.forget()); arrayToRelease.AppendElement(mPreflightChannel.forget()); + arrayToRelease.AppendElement(mDNSPrefetch.forget()); NS_DispatchToMainThread(new ProxyReleaseRunnable(std::move(arrayToRelease))); }