diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index 10df6c8435e6..257c6885eee8 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -78,7 +78,7 @@ protected: virtual ~CompositableHost(); public: - NS_INLINE_DECL_REFCOUNTING(CompositableHost) + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableHost) explicit CompositableHost(const TextureInfo& aTextureInfo); static already_AddRefed Create(const TextureInfo& aTextureInfo); diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 8b8ff296834f..dc77a96d007a 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -295,18 +295,17 @@ ImageBridgeChild::ShutdownStep2(SynchronousTask* aTask) MOZ_ASSERT(InImageBridgeChildThread(), "Should be in ImageBridgeChild thread."); - - if (!mCalledClose) { - Close(); - mCalledClose = true; - } + Close(); } void ImageBridgeChild::ActorDestroy(ActorDestroyReason aWhy) { mCanSend = false; - mCalledClose = true; + { + MutexAutoLock lock(mContainerMapLock); + mImageContainers.Clear(); + } } void @@ -338,7 +337,7 @@ ImageBridgeChild::CreateCanvasClientSync(SynchronousTask* aTask, ImageBridgeChild::ImageBridgeChild() : mCanSend(false) - , mCalledClose(false) + , mDestroyed(false) , mFwdTransactionId(0) , mContainerMapLock("ImageBridgeChild.mContainerMapLock") { @@ -736,6 +735,8 @@ ImageBridgeChild::WillShutdown() task.Wait(); } + + mDestroyed = true; } void @@ -998,6 +999,12 @@ ImageBridgeChild::DeallocShmem(ipc::Shmem& aShmem) return PImageBridgeChild::DeallocShmem(aShmem); } + // If we can't post a task, then we definitely cannot send, so there's + // no reason to queue up this send. + if (!CanPostTask()) { + return false; + } + SynchronousTask task("AllocatorProxy Dealloc"); bool result = false; @@ -1150,10 +1157,32 @@ bool ImageBridgeChild::IsSameProcess() const return OtherPid() == base::GetCurrentProcId(); } +bool +ImageBridgeChild::CanPostTask() const +{ + // During shutdown, the cycle collector may free objects that are holding a + // reference to ImageBridgeChild. Since this happens on the main thread, + // ImageBridgeChild will attempt to post a task to the ImageBridge thread. + // However the thread manager has already been shut down, so the task cannot + // post. + // + // It's okay if this races. We only care about the shutdown case where + // everything's happening on the main thread. Even if it races outside of + // shutdown, it's still harmless to post the task, since the task must + // check CanSend(). + return !mDestroyed; +} + void ImageBridgeChild::ReleaseCompositable(const CompositableHandle& aHandle) { if (!InImageBridgeChildThread()) { + // If we can't post a task, then we definitely cannot send, so there's + // no reason to queue up this send. + if (!CanPostTask()) { + return; + } + RefPtr runnable = WrapRunnable( RefPtr(this), &ImageBridgeChild::ReleaseCompositable, diff --git a/gfx/layers/ipc/ImageBridgeChild.h b/gfx/layers/ipc/ImageBridgeChild.h index 46ad683ddfa7..82ca193ff481 100644 --- a/gfx/layers/ipc/ImageBridgeChild.h +++ b/gfx/layers/ipc/ImageBridgeChild.h @@ -360,6 +360,7 @@ protected: void DeallocPImageBridgeChild() override; bool CanSend() const; + bool CanPostTask() const; static void ShutdownSingleton(); @@ -367,7 +368,7 @@ private: CompositableTransaction* mTxn; bool mCanSend; - bool mCalledClose; + mozilla::Atomic mDestroyed; /** * Transaction id of CompositableForwarder. diff --git a/gfx/layers/ipc/ImageBridgeParent.cpp b/gfx/layers/ipc/ImageBridgeParent.cpp index 50fb1ce49235..ddd168a167bb 100644 --- a/gfx/layers/ipc/ImageBridgeParent.cpp +++ b/gfx/layers/ipc/ImageBridgeParent.cpp @@ -104,6 +104,7 @@ ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy) { // Can't alloc/dealloc shmems from now on. mClosed = true; + mCompositables.clear(); MessageLoop::current()->PostTask(NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy)); diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 5e97c5326017..ce6cfd882d9d 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -94,6 +94,7 @@ void LayerTransactionParent::Destroy() { mDestroyed = true; + mCompositables.clear(); } mozilla::ipc::IPCResult