forked from mirrors/gecko-dev
Bug 1875528 - Part 6: Allow cycle-collecting the strong IPDL Manager reference, r=mccr8
There are a few IPDL actors which are cycle-collected, including `PBrowser`, `PContent`, and `PWindowGlobal`. This patch adds support for these actors to traverse and unlink the new strong Manager() reference added by IPDL, allowing cycles containing these actors to be properly unlinked and avoiding leaks. Differential Revision: https://phabricator.services.mozilla.com/D198629
This commit is contained in:
parent
de742b93d4
commit
33e1dcc9e0
5 changed files with 62 additions and 6 deletions
|
|
@ -265,7 +265,22 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowserParent)
|
|||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
NS_IMPL_CYCLE_COLLECTION_WEAK(BrowserParent, mFrameLoader, mBrowsingContext)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(BrowserParent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BrowserParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameLoader)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)
|
||||
tmp->UnlinkManager();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCE
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BrowserParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(Manager())
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(BrowserParent)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(BrowserParent)
|
||||
|
||||
|
|
|
|||
|
|
@ -867,9 +867,26 @@ nsISupports* WindowGlobalChild::GetParentObject() {
|
|||
return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_WEAK_PTR(WindowGlobalChild, mWindowGlobal,
|
||||
mContainerFeaturePolicy,
|
||||
mWindowContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WindowGlobalChild)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WindowGlobalChild)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContainerFeaturePolicy)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowContext)
|
||||
tmp->UnlinkManager();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_PTR
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WindowGlobalChild)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContainerFeaturePolicy)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowContext)
|
||||
if (!tmp->IsInProcess()) {
|
||||
CycleCollectionNoteChild(cb, static_cast<BrowserChild*>(tmp->Manager()),
|
||||
"Manager()");
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WindowGlobalChild)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
|
|
|
|||
|
|
@ -1713,8 +1713,22 @@ IPCResult WindowGlobalParent::RecvOnInitialStorageAccess() {
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(WindowGlobalParent, WindowContext,
|
||||
mPageUseCountersWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(WindowGlobalParent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WindowGlobalParent,
|
||||
WindowContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPageUseCountersWindow)
|
||||
tmp->UnlinkManager();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WindowGlobalParent,
|
||||
WindowContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPageUseCountersWindow)
|
||||
if (!tmp->IsInProcess()) {
|
||||
CycleCollectionNoteChild(cb, static_cast<BrowserParent*>(tmp->Manager()),
|
||||
"Manager()");
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WindowGlobalParent,
|
||||
WindowContext)
|
||||
|
|
|
|||
|
|
@ -504,6 +504,11 @@ void IProtocol::SetManagerAndRegister(IRefCountedProtocol* aManager,
|
|||
aManager->RegisterID(this, aId);
|
||||
}
|
||||
|
||||
void IProtocol::UnlinkManager() {
|
||||
mToplevel = nullptr;
|
||||
mManager = nullptr;
|
||||
}
|
||||
|
||||
bool IProtocol::ChannelSend(UniquePtr<IPC::Message> aMsg) {
|
||||
if (CanSend()) {
|
||||
// NOTE: This send call failing can only occur during toplevel channel
|
||||
|
|
|
|||
|
|
@ -241,6 +241,11 @@ class IProtocol : public HasResultCodes {
|
|||
// calls SetManager.
|
||||
void SetManager(IRefCountedProtocol* aManager);
|
||||
|
||||
// Clear `mManager` and `mToplevel` to nullptr. Only intended to be called
|
||||
// within the unlink implementation of cycle collected IPDL actors with cycle
|
||||
// collected managers.
|
||||
void UnlinkManager();
|
||||
|
||||
// Sets the manager for the protocol and registers the protocol with
|
||||
// its manager, setting up channels for the protocol as well. Not
|
||||
// for use outside of IPDL.
|
||||
|
|
|
|||
Loading…
Reference in a new issue