diff --git a/accessible/ipc/DocAccessibleChild.h b/accessible/ipc/DocAccessibleChild.h index 01673ba689a6..0a6164cce898 100644 --- a/accessible/ipc/DocAccessibleChild.h +++ b/accessible/ipc/DocAccessibleChild.h @@ -24,9 +24,7 @@ class AccShowEvent; */ class DocAccessibleChild : public PDocAccessibleChild { public: - DocAccessibleChild(DocAccessible* aDoc, - mozilla::ipc::IRefCountedProtocol* aManager) - : mDoc(aDoc) { + DocAccessibleChild(DocAccessible* aDoc, IProtocol* aManager) : mDoc(aDoc) { MOZ_COUNT_CTOR(DocAccessibleChild); SetManager(aManager); } diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp index 12c2004fdb05..830ad8579a39 100644 --- a/dom/ipc/BrowserChild.cpp +++ b/dom/ipc/BrowserChild.cpp @@ -2150,23 +2150,18 @@ bool BrowserChild::DeallocPDocAccessibleChild( #endif RefPtr BrowserChild::GetVsyncChild() { - // Initializing VsyncMainChild here turns on per-BrowserChild Vsync for a + // Initializing mVsyncChild here turns on per-BrowserChild Vsync for a // given platform. Note: this only makes sense if nsWindow returns a // window-specific VsyncSource. #if defined(MOZ_WAYLAND) - if (IsWaylandEnabled()) { - if (auto* actor = static_cast( - LoneManagedOrNullAsserts(ManagedPVsyncChild()))) { - return actor; + if (IsWaylandEnabled() && !mVsyncChild) { + mVsyncChild = MakeRefPtr(); + if (!SendPVsyncConstructor(mVsyncChild)) { + mVsyncChild = nullptr; } - auto actor = MakeRefPtr(); - if (!SendPVsyncConstructor(actor)) { - return nullptr; - } - return actor; } #endif - return nullptr; + return mVsyncChild; } mozilla::ipc::IPCResult BrowserChild::RecvLoadRemoteScript( diff --git a/dom/ipc/BrowserChild.h b/dom/ipc/BrowserChild.h index 62ad71501c51..ddbf8f0b74fd 100644 --- a/dom/ipc/BrowserChild.h +++ b/dom/ipc/BrowserChild.h @@ -748,6 +748,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor, Maybe mLayersConnectRequested; EffectsInfo mEffectsInfo; + RefPtr mVsyncChild; + RefPtr mAPZEventState; // Position of client area relative to the outer window diff --git a/dom/ipc/BrowserParent.cpp b/dom/ipc/BrowserParent.cpp index 8a4461f9881a..d369556588eb 100644 --- a/dom/ipc/BrowserParent.cpp +++ b/dom/ipc/BrowserParent.cpp @@ -265,22 +265,7 @@ 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_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_COLLECTION_WEAK(BrowserParent, mFrameLoader, mBrowsingContext) NS_IMPL_CYCLE_COLLECTING_ADDREF(BrowserParent) NS_IMPL_CYCLE_COLLECTING_RELEASE(BrowserParent) @@ -307,6 +292,7 @@ BrowserParent::BrowserParent(ContentParent* aManager, const TabId& aTabId, mUpdatedDimensions(false), mSizeMode(nsSizeMode_Normal), mCreatingWindow(false), + mVsyncParent(nullptr), mMarkedDestroying(false), mIsDestroyed(false), mRemoteTargetSetsCursor(false), @@ -1405,19 +1391,21 @@ IPCResult BrowserParent::RecvNewWindowGlobal( return IPC_OK(); } -already_AddRefed BrowserParent::AllocPVsyncParent() { - return MakeAndAddRef(); +PVsyncParent* BrowserParent::AllocPVsyncParent() { + MOZ_ASSERT(!mVsyncParent); + mVsyncParent = new VsyncParent(); + UpdateVsyncParentVsyncDispatcher(); + return mVsyncParent.get(); } -IPCResult BrowserParent::RecvPVsyncConstructor(PVsyncParent* aActor) { - UpdateVsyncParentVsyncDispatcher(); - return IPC_OK(); +bool BrowserParent::DeallocPVsyncParent(PVsyncParent* aActor) { + MOZ_ASSERT(aActor); + mVsyncParent = nullptr; + return true; } void BrowserParent::UpdateVsyncParentVsyncDispatcher() { - VsyncParent* actor = static_cast( - LoneManagedOrNullAsserts(ManagedPVsyncParent())); - if (!actor) { + if (!mVsyncParent) { return; } @@ -1426,7 +1414,7 @@ void BrowserParent::UpdateVsyncParentVsyncDispatcher() { if (!vsyncDispatcher) { vsyncDispatcher = gfxPlatform::GetPlatform()->GetGlobalVsyncDispatcher(); } - actor->UpdateVsyncDispatcher(vsyncDispatcher); + mVsyncParent->UpdateVsyncDispatcher(vsyncDispatcher); } } diff --git a/dom/ipc/BrowserParent.h b/dom/ipc/BrowserParent.h index a81d0ce2f543..4d4ae287b476 100644 --- a/dom/ipc/BrowserParent.h +++ b/dom/ipc/BrowserParent.h @@ -423,9 +423,9 @@ class BrowserParent final : public PBrowserParent, const nsString& aTitle, const nsString& aInitialColor, const nsTArray& aDefaultColors); - already_AddRefed AllocPVsyncParent(); + PVsyncParent* AllocPVsyncParent(); - mozilla::ipc::IPCResult RecvPVsyncConstructor(PVsyncParent* aActor) override; + bool DeallocPVsyncParent(PVsyncParent* aActor); #ifdef ACCESSIBILITY PDocAccessibleParent* AllocPDocAccessibleParent( @@ -941,6 +941,8 @@ class BrowserParent final : public PBrowserParent, nsTArray mVerifyDropLinks; + RefPtr mVsyncParent; + #ifdef DEBUG int32_t mActiveSupressDisplayportCount = 0; #endif diff --git a/dom/ipc/WindowGlobalChild.cpp b/dom/ipc/WindowGlobalChild.cpp index dff3cb58fe46..ec2811f972ae 100644 --- a/dom/ipc/WindowGlobalChild.cpp +++ b/dom/ipc/WindowGlobalChild.cpp @@ -878,26 +878,9 @@ nsISupports* WindowGlobalChild::GetParentObject() { return xpc::NativeGlobal(xpc::PrivilegedJunkScope()); } -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(tmp->Manager()), - "Manager()"); - } -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_WEAK_PTR(WindowGlobalChild, mWindowGlobal, + mContainerFeaturePolicy, + mWindowContext) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WindowGlobalChild) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY diff --git a/dom/ipc/WindowGlobalParent.cpp b/dom/ipc/WindowGlobalParent.cpp index e52c514b6c3e..2a02d2246c38 100644 --- a/dom/ipc/WindowGlobalParent.cpp +++ b/dom/ipc/WindowGlobalParent.cpp @@ -1697,22 +1697,8 @@ IPCResult WindowGlobalParent::RecvSetCookies( aCookies, GetBrowsingContext()); } -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(tmp->Manager()), - "Manager()"); - } -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_INHERITED(WindowGlobalParent, WindowContext, + mPageUseCountersWindow) NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WindowGlobalParent, WindowContext) diff --git a/gfx/ipc/CanvasManagerChild.cpp b/gfx/ipc/CanvasManagerChild.cpp index 986457a20b83..eca803bc4b76 100644 --- a/gfx/ipc/CanvasManagerChild.cpp +++ b/gfx/ipc/CanvasManagerChild.cpp @@ -234,15 +234,14 @@ RefPtr CanvasManagerChild::GetCanvasChild() { } RefPtr CanvasManagerChild::GetWebGPUChild() { - if (PWebGPUChild* actor = LoneManagedOrNullAsserts(ManagedPWebGPUChild())) { - return static_cast(actor); + if (!mWebGPUChild) { + mWebGPUChild = MakeAndAddRef(); + if (!SendPWebGPUConstructor(mWebGPUChild)) { + mWebGPUChild = nullptr; + } } - auto actor = MakeRefPtr(); - if (!SendPWebGPUConstructor(actor)) { - return nullptr; - } - return actor; + return mWebGPUChild; } layers::ActiveResourceTracker* CanvasManagerChild::GetActiveResourceTracker() { diff --git a/gfx/ipc/CanvasManagerChild.h b/gfx/ipc/CanvasManagerChild.h index 27a6f6049868..6369d87ada7a 100644 --- a/gfx/ipc/CanvasManagerChild.h +++ b/gfx/ipc/CanvasManagerChild.h @@ -71,6 +71,7 @@ class CanvasManagerChild final : public PCanvasManagerChild { RefPtr mWorkerRef; RefPtr mCanvasChild; + RefPtr mWebGPUChild; UniquePtr mActiveResourceTracker; std::set mActiveCanvas; const uint32_t mId; diff --git a/ipc/glue/BackgroundImpl.cpp b/ipc/glue/BackgroundImpl.cpp index bf040a18a4fb..bba09c261ae8 100644 --- a/ipc/glue/BackgroundImpl.cpp +++ b/ipc/glue/BackgroundImpl.cpp @@ -561,12 +561,7 @@ class ChildImpl final : public BackgroundChildImpl { #endif } - // This type is threadsafe refcounted as actors managed by it may be destroyed - // after the thread it is bound to dies, and hold a reference to this object. - // - // It is _not_ safe to use this type or any methods on it from off of the - // thread it was created for. - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChildImpl, override) + NS_INLINE_DECL_REFCOUNTING(ChildImpl, override) private: // Forwarded from BackgroundChild. diff --git a/ipc/glue/Endpoint.cpp b/ipc/glue/Endpoint.cpp index 0e5677675fc8..3391f8b359f7 100644 --- a/ipc/glue/Endpoint.cpp +++ b/ipc/glue/Endpoint.cpp @@ -57,7 +57,7 @@ UntypedManagedEndpoint::~UntypedManagedEndpoint() { } bool UntypedManagedEndpoint::BindCommon(IProtocol* aActor, - IRefCountedProtocol* aManager) { + IProtocol* aManager) { MOZ_ASSERT(aManager); if (!mInner) { NS_WARNING("Cannot bind to invalid endpoint"); diff --git a/ipc/glue/Endpoint.h b/ipc/glue/Endpoint.h index e4d32a7119a1..d7eea94dfc60 100644 --- a/ipc/glue/Endpoint.h +++ b/ipc/glue/Endpoint.h @@ -214,7 +214,7 @@ class UntypedManagedEndpoint { ~UntypedManagedEndpoint() noexcept; - bool BindCommon(IProtocol* aActor, IRefCountedProtocol* aManager); + bool BindCommon(IProtocol* aActor, IProtocol* aManager); private: friend struct IPDLParamTraits; @@ -267,8 +267,7 @@ class ManagedEndpoint : public UntypedManagedEndpoint { ManagedEndpoint(const PrivateIPDLInterface&, IProtocol* aActor) : UntypedManagedEndpoint(aActor) {} - bool Bind(const PrivateIPDLInterface&, PFooSide* aActor, - IRefCountedProtocol* aManager, + bool Bind(const PrivateIPDLInterface&, PFooSide* aActor, IProtocol* aManager, ManagedContainer& aContainer) { if (!BindCommon(aActor, aManager)) { return false; diff --git a/ipc/glue/ProtocolUtils.cpp b/ipc/glue/ProtocolUtils.cpp index 5dadb8e5591e..709c77f5e725 100644 --- a/ipc/glue/ProtocolUtils.cpp +++ b/ipc/glue/ProtocolUtils.cpp @@ -257,6 +257,12 @@ ActorLifecycleProxy::ActorLifecycleProxy(IProtocol* aActor) : mActor(aActor) { MOZ_ASSERT(mActor->CanSend(), "Cannot create LifecycleProxy for non-connected actor!"); + // Take a reference to our manager's lifecycle proxy to try to hold it & + // ensure it doesn't die before us. + if (mActor->mManager) { + mManager = mActor->mManager->mLifecycleProxy; + } + // Record that we've taken our first reference to our actor. mActor->ActorAlloc(); } @@ -487,13 +493,13 @@ bool IProtocol::DeallocShmem(Shmem& aMem) { return ok; } -void IProtocol::SetManager(IRefCountedProtocol* aManager) { +void IProtocol::SetManager(IProtocol* aManager) { MOZ_RELEASE_ASSERT(!mManager || mManager == aManager); mManager = aManager; mToplevel = aManager->mToplevel; } -void IProtocol::SetManagerAndRegister(IRefCountedProtocol* aManager) { +void IProtocol::SetManagerAndRegister(IProtocol* aManager) { // Set the manager prior to registering so registering properly inherits // the manager's event target. SetManager(aManager); @@ -501,8 +507,7 @@ void IProtocol::SetManagerAndRegister(IRefCountedProtocol* aManager) { aManager->Register(this); } -void IProtocol::SetManagerAndRegister(IRefCountedProtocol* aManager, - int32_t aId) { +void IProtocol::SetManagerAndRegister(IProtocol* aManager, int32_t aId) { // Set the manager prior to registering so registering properly inherits // the manager's event target. SetManager(aManager); @@ -510,11 +515,6 @@ void IProtocol::SetManagerAndRegister(IRefCountedProtocol* aManager, aManager->RegisterID(this, aId); } -void IProtocol::UnlinkManager() { - mToplevel = nullptr; - mManager = nullptr; -} - bool IProtocol::ChannelSend(UniquePtr aMsg) { if (CanSend()) { // NOTE: This send call failing can only occur during toplevel channel diff --git a/ipc/glue/ProtocolUtils.h b/ipc/glue/ProtocolUtils.h index df35d7d01371..842bc229867d 100644 --- a/ipc/glue/ProtocolUtils.h +++ b/ipc/glue/ProtocolUtils.h @@ -215,7 +215,7 @@ class IProtocol : public HasResultCodes { const char* GetProtocolName() const { return ProtocolIdToName(mProtocolId); } int32_t Id() const { return mId; } - IRefCountedProtocol* Manager() const { return mManager; } + IProtocol* Manager() const { return mManager; } ActorLifecycleProxy* GetLifecycleProxy() { return mLifecycleProxy; } WeakActorLifecycleProxy* GetWeakLifecycleProxy(); @@ -259,18 +259,13 @@ class IProtocol : public HasResultCodes { // We have separate functions because the accessibility code manually // 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(); + void SetManager(IProtocol* aManager); // 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. - void SetManagerAndRegister(IRefCountedProtocol* aManager); - void SetManagerAndRegister(IRefCountedProtocol* aManager, int32_t aId); + void SetManagerAndRegister(IProtocol* aManager); + void SetManagerAndRegister(IProtocol* aManager, int32_t aId); // Helpers for calling `Send` on our underlying IPC channel. bool ChannelSend(UniquePtr aMsg); @@ -338,7 +333,7 @@ class IProtocol : public HasResultCodes { Side mSide; LinkStatus mLinkStatus; ActorLifecycleProxy* mLifecycleProxy; - RefPtr mManager; + IProtocol* mManager; IToplevelProtocol* mToplevel; }; @@ -671,6 +666,10 @@ class ActorLifecycleProxy { IProtocol* MOZ_NON_OWNING_REF mActor; + // Hold a reference to the actor's manager's ActorLifecycleProxy to help + // prevent it from dying while we're still alive! + RefPtr mManager; + // When requested, the current self-referencing weak reference for this // ActorLifecycleProxy. RefPtr mWeakProxy;