diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index b74dd097bf4..48405f89d43 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -1275,8 +1275,10 @@ class CrossProcessCompositorParent : public PCompositorParent, NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CrossProcessCompositorParent) public: - CrossProcessCompositorParent() {} - virtual ~CrossProcessCompositorParent() {} + CrossProcessCompositorParent(Transport* aTransport) + : mTransport(aTransport) + {} + virtual ~CrossProcessCompositorParent(); virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; @@ -1316,6 +1318,7 @@ private: // reference to top-level actors. So we hold a reference to // ourself. This is released (deferred) in ActorDestroy(). nsRefPtr mSelfRef; + Transport* mTransport; }; static void @@ -1331,7 +1334,7 @@ OpenCompositor(CrossProcessCompositorParent* aCompositor, CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess) { nsRefPtr cpcp = - new CrossProcessCompositorParent(); + new CrossProcessCompositorParent(aTransport); ProcessHandle handle; if (!base::OpenProcessHandle(aOtherProcess, &handle)) { // XXX need to kill |aOtherProcess|, it's boned @@ -1426,9 +1429,15 @@ CrossProcessCompositorParent::ShadowLayersUpdated( void CrossProcessCompositorParent::DeferredDestroy() { - mSelfRef = NULL; + mSelfRef = nullptr; // |this| was just destroyed, hands off } +CrossProcessCompositorParent::~CrossProcessCompositorParent() +{ + XRE_GetIOMessageLoop()->PostTask(FROM_HERE, + new DeleteTask(mTransport)); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 6069cf0db0d..d1f1349beb4 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -202,7 +202,7 @@ bool ImageBridgeChild::StartUpOnThread(Thread* aThread) } sImageBridgeChildSingleton = new ImageBridgeChild(); ImageBridgeParent* imageBridgeParent = new ImageBridgeParent( - CompositorParent::CompositorLoop()); + CompositorParent::CompositorLoop(), nullptr); sImageBridgeChildSingleton->ConnectAsync(imageBridgeParent); return true; } else { diff --git a/gfx/layers/ipc/ImageBridgeParent.cpp b/gfx/layers/ipc/ImageBridgeParent.cpp index 348f34e5f65..f798c8bed9d 100644 --- a/gfx/layers/ipc/ImageBridgeParent.cpp +++ b/gfx/layers/ipc/ImageBridgeParent.cpp @@ -18,15 +18,27 @@ namespace mozilla { namespace layers { -ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop) -: mMessageLoop(aLoop) +ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport) + : mMessageLoop(aLoop) + , mTransport(aTransport) { ImageContainerParent::CreateSharedImageMap(); } ImageBridgeParent::~ImageBridgeParent() { - ImageContainerParent::DestroySharedImageMap(); + if (mTransport) { + XRE_GetIOMessageLoop()->PostTask(FROM_HERE, + new DeleteTask(mTransport)); + } +} + +void +ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy) +{ + MessageLoop::current()->PostTask( + FROM_HERE, + NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy)); } static void @@ -47,11 +59,12 @@ ImageBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess) } MessageLoop* loop = CompositorParent::CompositorLoop(); - ImageBridgeParent* bridge = new ImageBridgeParent(loop); + nsRefPtr bridge = new ImageBridgeParent(loop, aTransport); + bridge->mSelfRef = bridge; loop->PostTask(FROM_HERE, NewRunnableFunction(ConnectImageBridgeInParentProcess, - bridge, aTransport, processHandle)); - return bridge; + bridge.get(), aTransport, processHandle)); + return bridge.get(); } bool ImageBridgeParent::RecvStop() @@ -116,6 +129,12 @@ MessageLoop * ImageBridgeParent::GetMessageLoop() { return mMessageLoop; } +void +ImageBridgeParent::DeferredDestroy() +{ + mSelfRef = nullptr; + // |this| was just destroyed, hands off +} } // layers } // mozilla diff --git a/gfx/layers/ipc/ImageBridgeParent.h b/gfx/layers/ipc/ImageBridgeParent.h index 4d8a30d5c1f..94b0baef4ef 100644 --- a/gfx/layers/ipc/ImageBridgeParent.h +++ b/gfx/layers/ipc/ImageBridgeParent.h @@ -18,11 +18,14 @@ class CompositorParent; */ class ImageBridgeParent : public PImageBridgeParent { -public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageBridgeParent) - ImageBridgeParent(MessageLoop* aLoop); +public: + ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport); ~ImageBridgeParent(); + virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + static PImageBridgeParent* Create(Transport* aTransport, ProcessId aOtherProcess); @@ -43,7 +46,13 @@ public: MessageLoop * GetMessageLoop(); private: - MessageLoop * mMessageLoop; + void DeferredDestroy(); + + MessageLoop* mMessageLoop; + Transport* mTransport; + // This keeps us alive until ActorDestroy(), at which point we do a + // deferred destruction of ourselves. + nsRefPtr mSelfRef; }; } // layers diff --git a/gfx/layers/ipc/ImageContainerParent.cpp b/gfx/layers/ipc/ImageContainerParent.cpp index 6db879a8876..482961545c4 100644 --- a/gfx/layers/ipc/ImageContainerParent.cpp +++ b/gfx/layers/ipc/ImageContainerParent.cpp @@ -6,6 +6,7 @@ #include "mozilla/layers/ImageContainerParent.h" #include "mozilla/layers/ImageBridgeParent.h" #include "mozilla/layers/SharedImageUtils.h" +#include "mozilla/unused.h" #include "CompositorParent.h" namespace mozilla { @@ -29,7 +30,7 @@ bool ImageContainerParent::RecvPublishImage(const SharedImage& aImage) } if (prevImage && !mStop) { - SendReturnImage(*prevImage); + unused << SendReturnImage(*prevImage); delete prevImage; } return true; @@ -92,6 +93,8 @@ struct ImageIDPair { }; typedef nsTArray SharedImageMap; +// We currently leak this, because there's not a good time to clean it +// up. We're not on the main thread so can't use ClearOnShutdown(). SharedImageMap *sSharedImageMap = nullptr; static const int SHAREDIMAGEMAP_INVALID_INDEX = -1;