From c6649f32c4edf56f91541df6ae1d4bfe15d1179b Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Wed, 29 May 2024 17:01:27 +0800 Subject: [PATCH] Make sure to null out ChannelEventQueue::mOwner when object is released Conflict :NA Reference:https://hg.mozilla.org/integration/autoland/rev/2c34e2c06639132ae6a00b440c8835b2a44f42ad --- netwerk/ipc/ChannelEventQueue.cpp | 11 ++++++++++- netwerk/ipc/ChannelEventQueue.h | 5 +++++ netwerk/protocol/http/HttpChannelChild.cpp | 1 + netwerk/protocol/http/HttpChannelParent.cpp | 1 + netwerk/protocol/http/HttpTransactionParent.cpp | 1 + netwerk/protocol/websocket/WebSocketChannelChild.cpp | 1 + .../extensions/webrequest/StreamFilterParent.cpp | 1 + 7 files changed, 20 insertions(+), 1 deletion(-) diff --git a/netwerk/ipc/ChannelEventQueue.cpp b/netwerk/ipc/ChannelEventQueue.cpp index c02f892ba8..ba5235b62e 100644 --- a/netwerk/ipc/ChannelEventQueue.cpp +++ b/netwerk/ipc/ChannelEventQueue.cpp @@ -34,7 +34,12 @@ void ChannelEventQueue::FlushQueue() { // Events flushed could include destruction of channel (and our own // destructor) unless we make sure its refcount doesn't drop to 0 while this // method is running. - nsCOMPtr kungFuDeathGrip(mOwner); + nsCOMPtr kungFuDeathGrip; + { + MutexAutoLock lock(mMutex); + kungFuDeathGrip = mOwner; + } + mozilla::Unused << kungFuDeathGrip; // Not used in this function #ifdef DEBUG @@ -156,6 +161,10 @@ void ChannelEventQueue::ResumeInternal() { nsCOMPtr mOwner; }; + if (!mOwner) { + return; + } + // Worker thread requires a CancelableRunnable. RefPtr event = new CompleteResumeRunnable(this, mOwner); diff --git a/netwerk/ipc/ChannelEventQueue.h b/netwerk/ipc/ChannelEventQueue.h index 650ee5b96f..aedbc00c63 100644 --- a/netwerk/ipc/ChannelEventQueue.h +++ b/netwerk/ipc/ChannelEventQueue.h @@ -171,6 +171,11 @@ class ChannelEventQueue final { // dispatched in a new event on the current thread. void Resume(); + void NotifyReleasingOwner() { + MutexAutoLock lock(mMutex); + mOwner = nullptr; + } + private: // Private destructor, to discourage deletion outside of Release(): ~ChannelEventQueue() = default; diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index 2949f7f35c..ba06148c61 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -228,6 +228,7 @@ HttpChannelChild::~HttpChannelChild() { mLoadInfo->RedirectChainIncludingInternalRedirects().Length(), flags); } #endif + mEventQ->NotifyReleasingOwner(); ReleaseMainThreadOnlyReferences(); } diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 9ebae5fc7a..40ea4283cf 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -1058,6 +1058,7 @@ void HttpChannelParent::ContinueRedirect2Verify(const nsresult& aResult) { mRedirectCallback->OnRedirectVerifyCallback(aResult); mRedirectCallback = nullptr; } + mEventQ->NotifyReleasingOwner(); } mozilla::ipc::IPCResult HttpChannelParent::RecvDocumentChannelCleanup( diff --git a/netwerk/protocol/http/HttpTransactionParent.cpp b/netwerk/protocol/http/HttpTransactionParent.cpp index 041ecb804d..37d0e996c8 100644 --- a/netwerk/protocol/http/HttpTransactionParent.cpp +++ b/netwerk/protocol/http/HttpTransactionParent.cpp @@ -99,6 +99,7 @@ HttpTransactionParent::HttpTransactionParent(bool aIsDocumentLoad) HttpTransactionParent::~HttpTransactionParent() { LOG(("Destroying HttpTransactionParent @%p\n", this)); + mEventQ->NotifyReleasingOwner(); } //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/websocket/WebSocketChannelChild.cpp b/netwerk/protocol/websocket/WebSocketChannelChild.cpp index a9b7a52bb7..e0d2b2137c 100644 --- a/netwerk/protocol/websocket/WebSocketChannelChild.cpp +++ b/netwerk/protocol/websocket/WebSocketChannelChild.cpp @@ -63,6 +63,7 @@ WebSocketChannelChild::WebSocketChannelChild(bool aEncrypted) WebSocketChannelChild::~WebSocketChannelChild() { LOG(("WebSocketChannelChild::~WebSocketChannelChild() %p\n", this)); + mEventQ->NotifyReleasingOwner(); } void WebSocketChannelChild::AddIPDLReference() { diff --git a/toolkit/components/extensions/webrequest/StreamFilterParent.cpp b/toolkit/components/extensions/webrequest/StreamFilterParent.cpp index 6632712fbf..aac58f2871 100644 --- a/toolkit/components/extensions/webrequest/StreamFilterParent.cpp +++ b/toolkit/components/extensions/webrequest/StreamFilterParent.cpp @@ -106,6 +106,7 @@ StreamFilterParent::~StreamFilterParent() { NS_ReleaseOnMainThread("StreamFilterParent::mOrigListener", mOrigListener.forget()); NS_ReleaseOnMainThread("StreamFilterParent::mContext", mContext.forget()); + mQueue->NotifyReleasingOwner(); } auto StreamFilterParent::Create(dom::ContentParent* aContentParent, -- 2.33.0