From b3c3ae76f7605974b882d2981876815d4266299b Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 7 May 2014 10:22:21 -0400 Subject: [PATCH] Backed out changeset d7d7cc47bcc6 (bug 924622) for bustage. CLOSED TREE --- gfx/layers/client/CompositableClient.cpp | 1 - gfx/layers/ipc/CompositorParent.cpp | 4 - gfx/layers/ipc/ImageBridgeChild.cpp | 137 ++++++----------------- gfx/layers/ipc/ImageBridgeChild.h | 11 +- gfx/layers/ipc/ImageBridgeParent.cpp | 9 +- gfx/layers/ipc/ImageBridgeParent.h | 5 +- gfx/layers/ipc/PImageBridge.ipdl | 17 ++- gfx/thebes/gfxPlatform.cpp | 10 ++ xpcom/build/nsXPComInit.cpp | 14 +-- 9 files changed, 65 insertions(+), 143 deletions(-) diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index 619569a316a6..af370c748ef6 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -179,6 +179,5 @@ CompositableClient::OnTransaction() { } - } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 83466d934a79..0819af4ab0d0 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -87,9 +87,6 @@ static MessageLoop* sMainLoop = nullptr; static PlatformThreadId sCompositorThreadID = 0; static MessageLoop* sCompositorLoop = nullptr; -// See ImageBridgeChild.cpp -void ReleaseImageBridgeParentSingleton(); - static void DeferredDeleteCompositorParent(CompositorParent* aNowReadyToDie) { aNowReadyToDie->Release(); @@ -98,7 +95,6 @@ static void DeferredDeleteCompositorParent(CompositorParent* aNowReadyToDie) static void DeleteCompositorThread() { if (NS_IsMainThread()){ - ReleaseImageBridgeParentSingleton(); delete sCompositorThread; sCompositorThread = nullptr; sCompositorLoop = nullptr; diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index e60f54e8fbdf..6cae11212454 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -165,50 +165,29 @@ static StaticRefPtr sImageBridgeChildSingleton; static StaticRefPtr sImageBridgeParentSingleton; static Thread *sImageBridgeChildThread = nullptr; -void ReleaseImageBridgeParentSingleton() { - sImageBridgeParentSingleton = nullptr; -} - - // dispatched function -static void ImageBridgeShutdownStep1(ReentrantMonitor *aBarrier, bool *aDone) +static void StopImageBridgeSync(ReentrantMonitor *aBarrier, bool *aDone) { ReentrantMonitorAutoEnter autoMon(*aBarrier); NS_ABORT_IF_FALSE(InImageBridgeChildThread(), "Should be in ImageBridgeChild thread."); if (sImageBridgeChildSingleton) { - // Force all managed protocols to shut themselves down cleanly - InfallibleTArray compositables; - sImageBridgeChildSingleton->ManagedPCompositableChild(compositables); - for (int i = compositables.Length() - 1; i >= 0; --i) { - CompositableClient::FromIPDLActor(compositables[i])->Destroy(); - } - InfallibleTArray textures; - sImageBridgeChildSingleton->ManagedPTextureChild(textures); - for (int i = textures.Length() - 1; i >= 0; --i) { - TextureClient::AsTextureClient(textures[i])->ForceRemove(); - } - sImageBridgeChildSingleton->SendWillStop(); - sImageBridgeChildSingleton->MarkShutDown(); - // From now on, no message can be sent through the image bridge from the - // client side except the final Stop message. + sImageBridgeChildSingleton->SendStop(); } *aDone = true; aBarrier->NotifyAll(); } // dispatched function -static void ImageBridgeShutdownStep2(ReentrantMonitor *aBarrier, bool *aDone) +static void DeleteImageBridgeSync(ReentrantMonitor *aBarrier, bool *aDone) { ReentrantMonitorAutoEnter autoMon(*aBarrier); NS_ABORT_IF_FALSE(InImageBridgeChildThread(), "Should be in ImageBridgeChild thread."); - - sImageBridgeChildSingleton->SendStop(); - sImageBridgeChildSingleton = nullptr; + sImageBridgeParentSingleton = nullptr; *aDone = true; aBarrier->NotifyAll(); } @@ -233,7 +212,6 @@ static void ConnectImageBridge(ImageBridgeChild * child, ImageBridgeParent * par } ImageBridgeChild::ImageBridgeChild() - : mShuttingDown(false) { mTxn = new CompositableTransaction(); } @@ -242,18 +220,10 @@ ImageBridgeChild::~ImageBridgeChild() delete mTxn; } -void -ImageBridgeChild::MarkShutDown() -{ - MOZ_ASSERT(!mShuttingDown); - mShuttingDown = true; -} - void ImageBridgeChild::Connect(CompositableClient* aCompositable) { MOZ_ASSERT(aCompositable); - MOZ_ASSERT(!mShuttingDown); uint64_t id = 0; PCompositableChild* child = SendPCompositableConstructor(aCompositable->GetTextureInfo(), &id); @@ -264,7 +234,6 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable) PCompositableChild* ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID) { - MOZ_ASSERT(!mShuttingDown); return CompositableClient::CreateIPDLActor(); } @@ -328,17 +297,6 @@ static void ReleaseImageClientNow(ImageClient* aClient) // static void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient) { - if (!IsCreated()) { - // CompositableClient::Release should normally happen in the ImageBridgeChild - // thread because it usually generate some IPDL messages. - // However, if we take this branch it means that the ImageBridgeChild - // has already shut down, along with the CompositableChild, which means no - // message will be sent and it is safe to run this code from any thread. - MOZ_ASSERT(aClient->GetIPDLActor() == nullptr); - aClient->Release(); - return; - } - sImageBridgeChildSingleton->GetMessageLoop()->PostTask( FROM_HERE, NewRunnableFunction(&ReleaseImageClientNow, aClient)); @@ -353,17 +311,6 @@ static void ReleaseTextureClientNow(TextureClient* aClient) // static void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient) { - if (!IsCreated()) { - // TextureClient::Release should normally happen in the ImageBridgeChild - // thread because it usually generate some IPDL messages. - // However, if we take this branch it means that the ImageBridgeChild - // has already shut down, along with the TextureChild, which means no - // message will be sent and it is safe to run this code from any thread. - MOZ_ASSERT(aClient->GetIPDLActor() == nullptr); - aClient->Release(); - return; - } - sImageBridgeChildSingleton->GetMessageLoop()->PostTask( FROM_HERE, NewRunnableFunction(&ReleaseTextureClientNow, aClient)); @@ -383,10 +330,6 @@ static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContaine void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient, ImageContainer* aContainer) { - if (!IsCreated()) { - return; - } - if (InImageBridgeChildThread()) { UpdateImageClientNow(aClient, aContainer); return; @@ -411,10 +354,6 @@ static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer, //static void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront) { - if (!IsCreated()) { - return; - } - if (InImageBridgeChildThread()) { FlushAllImagesNow(aClient, aContainer, aExceptFront); return; @@ -439,7 +378,6 @@ void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aCon void ImageBridgeChild::FlushAllImagesNow(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront) { MOZ_ASSERT(aClient); - MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown); sImageBridgeChildSingleton->BeginTransaction(); if (aContainer && !aExceptFront) { aContainer->ClearCurrentImage(); @@ -452,7 +390,6 @@ void ImageBridgeChild::FlushAllImagesNow(ImageClient* aClient, ImageContainer* a void ImageBridgeChild::BeginTransaction() { - MOZ_ASSERT(!mShuttingDown); MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?"); mTxn->Begin(); } @@ -474,7 +411,6 @@ private: void ImageBridgeChild::EndTransaction() { - MOZ_ASSERT(!mShuttingDown); MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?"); AutoEndTransaction _(mTxn); @@ -569,34 +505,9 @@ ImageBridgeChild::StartUpInChildProcess(Transport* aTransport, void ImageBridgeChild::ShutDown() { - MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!"); + NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!"); if (ImageBridgeChild::IsCreated()) { - MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown); - - { - ReentrantMonitor barrier("ImageBridge ShutdownStep1 lock"); - ReentrantMonitorAutoEnter autoMon(barrier); - - bool done = false; - sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE, - NewRunnableFunction(&ImageBridgeShutdownStep1, &barrier, &done)); - while (!done) { - barrier.Wait(); - } - } - - { - ReentrantMonitor barrier("ImageBridge ShutdownStep2 lock"); - ReentrantMonitorAutoEnter autoMon(barrier); - - bool done = false; - sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE, - NewRunnableFunction(&ImageBridgeShutdownStep2, &barrier, &done)); - while (!done) { - barrier.Wait(); - } - } - + ImageBridgeChild::DestroyBridge(); delete sImageBridgeChildThread; sImageBridgeChildThread = nullptr; } @@ -620,6 +531,35 @@ bool ImageBridgeChild::StartUpOnThread(Thread* aThread) } } +void ImageBridgeChild::DestroyBridge() +{ + if (!IsCreated()) { + return; + } + NS_ABORT_IF_FALSE(!InImageBridgeChildThread(), + "This method must not be called in this thread."); + // ...because we are about to dispatch synchronous messages to the + // ImageBridgeChild thread. + + ReentrantMonitor barrier("ImageBridgeDestroyTask lock"); + ReentrantMonitorAutoEnter autoMon(barrier); + + bool done = false; + sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE, + NewRunnableFunction(&StopImageBridgeSync, &barrier, &done)); + while (!done) { + barrier.Wait(); + } + + done = false; + sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE, + NewRunnableFunction(&DeleteImageBridgeSync, &barrier, &done)); + while (!done) { + barrier.Wait(); + } + +} + bool InImageBridgeChildThread() { return ImageBridgeChild::IsCreated() && @@ -669,7 +609,6 @@ ImageBridgeChild::CreateImageClient(CompositableType aType) TemporaryRef ImageBridgeChild::CreateImageClientNow(CompositableType aType) { - MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown); RefPtr client = ImageClient::CreateImageClient(aType, this, TextureFlags::NO_FLAGS); MOZ_ASSERT(client, "failed to create ImageClient"); @@ -684,7 +623,6 @@ ImageBridgeChild::AllocUnsafeShmem(size_t aSize, ipc::SharedMemory::SharedMemoryType aType, ipc::Shmem* aShmem) { - MOZ_ASSERT(!mShuttingDown); if (InImageBridgeChildThread()) { return PImageBridgeChild::AllocUnsafeShmem(aSize, aType, aShmem); } else { @@ -697,7 +635,6 @@ ImageBridgeChild::AllocShmem(size_t aSize, ipc::SharedMemory::SharedMemoryType aType, ipc::Shmem* aShmem) { - MOZ_ASSERT(!mShuttingDown); if (InImageBridgeChildThread()) { return PImageBridgeChild::AllocShmem(aSize, aType, aShmem); } else { @@ -806,7 +743,6 @@ PTextureChild* ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&, const TextureFlags&) { - MOZ_ASSERT(!mShuttingDown); return TextureClient::CreateIPDLActor(); } @@ -843,7 +779,6 @@ PTextureChild* ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData, TextureFlags aFlags) { - MOZ_ASSERT(!mShuttingDown); return SendPTextureConstructor(aSharedData, aFlags); } @@ -851,7 +786,6 @@ void ImageBridgeChild::RemoveTextureFromCompositable(CompositableClient* aCompositable, TextureClient* aTexture) { - MOZ_ASSERT(!mShuttingDown); if (aTexture->GetFlags() & TextureFlags::DEALLOCATE_CLIENT) { mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), nullptr, aTexture->GetIPDLActor())); @@ -875,7 +809,6 @@ static void RemoveTextureSync(TextureClient* aTexture, ReentrantMonitor* aBarrie void ImageBridgeChild::RemoveTexture(TextureClient* aTexture) { if (InImageBridgeChildThread()) { - MOZ_ASSERT(!mShuttingDown); aTexture->ForceRemove(); return; } diff --git a/gfx/layers/ipc/ImageBridgeChild.h b/gfx/layers/ipc/ImageBridgeChild.h index 23dcf14d6d4b..135e47bc95ad 100644 --- a/gfx/layers/ipc/ImageBridgeChild.h +++ b/gfx/layers/ipc/ImageBridgeChild.h @@ -129,6 +129,15 @@ public: */ static bool StartUpOnThread(base::Thread* aThread); + /** + * Destroys The ImageBridge protcol. + * + * The actual destruction happens synchronously on the ImageBridgeChild thread + * which means that if this function is called from another thread, the current + * thread will be paused until the destruction is done. + */ + static void DestroyBridge(); + /** * Returns true if the singleton has been created. * @@ -298,7 +307,6 @@ public: void SendPendingAsyncMessge(); - void MarkShutDown(); protected: ImageBridgeChild(); bool DispatchAllocShmemInternal(size_t aSize, @@ -307,7 +315,6 @@ protected: bool aUnsafe); CompositableTransaction* mTxn; - bool mShuttingDown; }; } // layers diff --git a/gfx/layers/ipc/ImageBridgeParent.cpp b/gfx/layers/ipc/ImageBridgeParent.cpp index e9db3fa8c063..0706e190da5c 100644 --- a/gfx/layers/ipc/ImageBridgeParent.cpp +++ b/gfx/layers/ipc/ImageBridgeParent.cpp @@ -138,7 +138,7 @@ ImageBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess) return bridge.get(); } -bool ImageBridgeParent::RecvWillStop() +bool ImageBridgeParent::RecvStop() { // If there is any texture still alive we have to force it to deallocate the // device data (GL textures, etc.) now because shortly after SenStop() returns @@ -153,13 +153,6 @@ bool ImageBridgeParent::RecvWillStop() return true; } -bool ImageBridgeParent::RecvStop() -{ - // Nothing to do. This message just serves as synchronization between the - // child and parent threads during shutdown. - return true; -} - static uint64_t GenImageContainerID() { static uint64_t sNextImageID = 1; diff --git a/gfx/layers/ipc/ImageBridgeParent.h b/gfx/layers/ipc/ImageBridgeParent.h index 4e8c46d12839..411c4ef76b55 100644 --- a/gfx/layers/ipc/ImageBridgeParent.h +++ b/gfx/layers/ipc/ImageBridgeParent.h @@ -76,10 +76,7 @@ public: virtual bool RecvChildAsyncMessages(const InfallibleTArray& aMessages) MOZ_OVERRIDE; - // Shutdown step 1 - virtual bool RecvWillStop() MOZ_OVERRIDE; - // Shutdown step 2 - virtual bool RecvStop() MOZ_OVERRIDE; + bool RecvStop() MOZ_OVERRIDE; MessageLoop * GetMessageLoop(); diff --git a/gfx/layers/ipc/PImageBridge.ipdl b/gfx/layers/ipc/PImageBridge.ipdl index b150c9b3b25d..451624d80ce0 100644 --- a/gfx/layers/ipc/PImageBridge.ipdl +++ b/gfx/layers/ipc/PImageBridge.ipdl @@ -36,16 +36,13 @@ parent: sync Update(CompositableOperation[] ops) returns (EditReply[] reply); async UpdateNoSwap(CompositableOperation[] ops); - // First step of the destruction sequence. This puts ImageBridge - // in a state in which it can't send asynchronous messages - // so as to not race with the upcomming Stop message and destruction. - // In the child side, the Stop message is not sent right after WillStop, - // it is scheduled in the ImageBridgeChild's message queue in order to ensure - // that all of the messages from the parent side have been received and processed - // before sending Stop, and that after Stop returns, there is no message in - // flight on any side and we can safely destroy the channel and threads. - sync WillStop(); - // Second step + // First step of the destruction sequence. This puts all the ImageContainerParents + // in a state in which they can't send asynchronous messages to their child + // counterpart so as to not race with the upcomming __delete__ message. + // In the child side, the __delete__ messages are not sent right after Stop, + // they are scheduled in the ImageBridgeChild's message queue in order to ensure + // that all the messages from the parent side have been received and processed + // before sending __delete__. sync Stop(); sync PCompositable(TextureInfo aInfo) returns (uint64_t id); diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index cf8594e1becc..dcafdd3d2fe3 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -500,6 +500,16 @@ gfxPlatform::Shutdown() mozilla::gl::GLContextProviderEGL::Shutdown(); #endif + // This will block this thread untill the ImageBridge protocol is completely + // deleted. + ImageBridgeChild::ShutDown(); +#ifdef MOZ_WIDGET_GONK + SharedBufferManagerChild::ShutDown(); +#endif + CompositorParent::ShutDown(); + + AsyncTransactionTracker::Finalize(); + delete gGfxPlatformPrefsLock; gfxPrefs::DestroySingleton(); diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp index ec82c9f6b4c4..958a1fde79e7 100644 --- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -14,11 +14,10 @@ #include "nsXPCOMPrivate.h" #include "nsXPCOMCIDInternal.h" +#include "prlink.h" + #include "mozilla/layers/ImageBridgeChild.h" #include "mozilla/layers/CompositorParent.h" -#include "mozilla/layers/AsyncTransactionTracker.h" - -#include "prlink.h" #include "nsCycleCollector.h" #include "nsObserverList.h" @@ -790,15 +789,6 @@ ShutdownXPCOM(nsIServiceManager* servMgr) } } - // This must happen after the shutdown of media and widgets, which - // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification. - layers::ImageBridgeChild::ShutDown(); -#ifdef MOZ_WIDGET_GONK - layers::SharedBufferManagerChild::ShutDown(); -#endif - layers::CompositorParent::ShutDown(); - layers::AsyncTransactionTracker::Finalize(); - NS_ProcessPendingEvents(thread); mozilla::scache::StartupCache::DeleteSingleton(); if (observerService)