Backed out changeset d7d7cc47bcc6 (bug 924622) for bustage.

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2014-05-07 10:22:21 -04:00
Родитель 0737ab5dba
Коммит b3c3ae76f7
9 изменённых файлов: 65 добавлений и 143 удалений

Просмотреть файл

@ -179,6 +179,5 @@ CompositableClient::OnTransaction()
{ {
} }
} // namespace layers } // namespace layers
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -87,9 +87,6 @@ static MessageLoop* sMainLoop = nullptr;
static PlatformThreadId sCompositorThreadID = 0; static PlatformThreadId sCompositorThreadID = 0;
static MessageLoop* sCompositorLoop = nullptr; static MessageLoop* sCompositorLoop = nullptr;
// See ImageBridgeChild.cpp
void ReleaseImageBridgeParentSingleton();
static void DeferredDeleteCompositorParent(CompositorParent* aNowReadyToDie) static void DeferredDeleteCompositorParent(CompositorParent* aNowReadyToDie)
{ {
aNowReadyToDie->Release(); aNowReadyToDie->Release();
@ -98,7 +95,6 @@ static void DeferredDeleteCompositorParent(CompositorParent* aNowReadyToDie)
static void DeleteCompositorThread() static void DeleteCompositorThread()
{ {
if (NS_IsMainThread()){ if (NS_IsMainThread()){
ReleaseImageBridgeParentSingleton();
delete sCompositorThread; delete sCompositorThread;
sCompositorThread = nullptr; sCompositorThread = nullptr;
sCompositorLoop = nullptr; sCompositorLoop = nullptr;

Просмотреть файл

@ -165,50 +165,29 @@ static StaticRefPtr<ImageBridgeChild> sImageBridgeChildSingleton;
static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton; static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton;
static Thread *sImageBridgeChildThread = nullptr; static Thread *sImageBridgeChildThread = nullptr;
void ReleaseImageBridgeParentSingleton() {
sImageBridgeParentSingleton = nullptr;
}
// dispatched function // dispatched function
static void ImageBridgeShutdownStep1(ReentrantMonitor *aBarrier, bool *aDone) static void StopImageBridgeSync(ReentrantMonitor *aBarrier, bool *aDone)
{ {
ReentrantMonitorAutoEnter autoMon(*aBarrier); ReentrantMonitorAutoEnter autoMon(*aBarrier);
NS_ABORT_IF_FALSE(InImageBridgeChildThread(), NS_ABORT_IF_FALSE(InImageBridgeChildThread(),
"Should be in ImageBridgeChild thread."); "Should be in ImageBridgeChild thread.");
if (sImageBridgeChildSingleton) { if (sImageBridgeChildSingleton) {
// Force all managed protocols to shut themselves down cleanly sImageBridgeChildSingleton->SendStop();
InfallibleTArray<PCompositableChild*> compositables;
sImageBridgeChildSingleton->ManagedPCompositableChild(compositables);
for (int i = compositables.Length() - 1; i >= 0; --i) {
CompositableClient::FromIPDLActor(compositables[i])->Destroy();
}
InfallibleTArray<PTextureChild*> 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.
} }
*aDone = true; *aDone = true;
aBarrier->NotifyAll(); aBarrier->NotifyAll();
} }
// dispatched function // dispatched function
static void ImageBridgeShutdownStep2(ReentrantMonitor *aBarrier, bool *aDone) static void DeleteImageBridgeSync(ReentrantMonitor *aBarrier, bool *aDone)
{ {
ReentrantMonitorAutoEnter autoMon(*aBarrier); ReentrantMonitorAutoEnter autoMon(*aBarrier);
NS_ABORT_IF_FALSE(InImageBridgeChildThread(), NS_ABORT_IF_FALSE(InImageBridgeChildThread(),
"Should be in ImageBridgeChild thread."); "Should be in ImageBridgeChild thread.");
sImageBridgeChildSingleton->SendStop();
sImageBridgeChildSingleton = nullptr; sImageBridgeChildSingleton = nullptr;
sImageBridgeParentSingleton = nullptr;
*aDone = true; *aDone = true;
aBarrier->NotifyAll(); aBarrier->NotifyAll();
} }
@ -233,7 +212,6 @@ static void ConnectImageBridge(ImageBridgeChild * child, ImageBridgeParent * par
} }
ImageBridgeChild::ImageBridgeChild() ImageBridgeChild::ImageBridgeChild()
: mShuttingDown(false)
{ {
mTxn = new CompositableTransaction(); mTxn = new CompositableTransaction();
} }
@ -242,18 +220,10 @@ ImageBridgeChild::~ImageBridgeChild()
delete mTxn; delete mTxn;
} }
void
ImageBridgeChild::MarkShutDown()
{
MOZ_ASSERT(!mShuttingDown);
mShuttingDown = true;
}
void void
ImageBridgeChild::Connect(CompositableClient* aCompositable) ImageBridgeChild::Connect(CompositableClient* aCompositable)
{ {
MOZ_ASSERT(aCompositable); MOZ_ASSERT(aCompositable);
MOZ_ASSERT(!mShuttingDown);
uint64_t id = 0; uint64_t id = 0;
PCompositableChild* child = PCompositableChild* child =
SendPCompositableConstructor(aCompositable->GetTextureInfo(), &id); SendPCompositableConstructor(aCompositable->GetTextureInfo(), &id);
@ -264,7 +234,6 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable)
PCompositableChild* PCompositableChild*
ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID) ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID)
{ {
MOZ_ASSERT(!mShuttingDown);
return CompositableClient::CreateIPDLActor(); return CompositableClient::CreateIPDLActor();
} }
@ -328,17 +297,6 @@ static void ReleaseImageClientNow(ImageClient* aClient)
// static // static
void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient) 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( sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
FROM_HERE, FROM_HERE,
NewRunnableFunction(&ReleaseImageClientNow, aClient)); NewRunnableFunction(&ReleaseImageClientNow, aClient));
@ -353,17 +311,6 @@ static void ReleaseTextureClientNow(TextureClient* aClient)
// static // static
void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient) 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( sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
FROM_HERE, FROM_HERE,
NewRunnableFunction(&ReleaseTextureClientNow, aClient)); NewRunnableFunction(&ReleaseTextureClientNow, aClient));
@ -383,10 +330,6 @@ static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContaine
void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient, void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient,
ImageContainer* aContainer) ImageContainer* aContainer)
{ {
if (!IsCreated()) {
return;
}
if (InImageBridgeChildThread()) { if (InImageBridgeChildThread()) {
UpdateImageClientNow(aClient, aContainer); UpdateImageClientNow(aClient, aContainer);
return; return;
@ -411,10 +354,6 @@ static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer,
//static //static
void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront) void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront)
{ {
if (!IsCreated()) {
return;
}
if (InImageBridgeChildThread()) { if (InImageBridgeChildThread()) {
FlushAllImagesNow(aClient, aContainer, aExceptFront); FlushAllImagesNow(aClient, aContainer, aExceptFront);
return; return;
@ -439,7 +378,6 @@ void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aCon
void ImageBridgeChild::FlushAllImagesNow(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront) void ImageBridgeChild::FlushAllImagesNow(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront)
{ {
MOZ_ASSERT(aClient); MOZ_ASSERT(aClient);
MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
sImageBridgeChildSingleton->BeginTransaction(); sImageBridgeChildSingleton->BeginTransaction();
if (aContainer && !aExceptFront) { if (aContainer && !aExceptFront) {
aContainer->ClearCurrentImage(); aContainer->ClearCurrentImage();
@ -452,7 +390,6 @@ void ImageBridgeChild::FlushAllImagesNow(ImageClient* aClient, ImageContainer* a
void void
ImageBridgeChild::BeginTransaction() ImageBridgeChild::BeginTransaction()
{ {
MOZ_ASSERT(!mShuttingDown);
MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?"); MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?");
mTxn->Begin(); mTxn->Begin();
} }
@ -474,7 +411,6 @@ private:
void void
ImageBridgeChild::EndTransaction() ImageBridgeChild::EndTransaction()
{ {
MOZ_ASSERT(!mShuttingDown);
MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?"); MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?");
AutoEndTransaction _(mTxn); AutoEndTransaction _(mTxn);
@ -569,34 +505,9 @@ ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
void ImageBridgeChild::ShutDown() 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()) { if (ImageBridgeChild::IsCreated()) {
MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown); ImageBridgeChild::DestroyBridge();
{
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();
}
}
delete sImageBridgeChildThread; delete sImageBridgeChildThread;
sImageBridgeChildThread = nullptr; 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() bool InImageBridgeChildThread()
{ {
return ImageBridgeChild::IsCreated() && return ImageBridgeChild::IsCreated() &&
@ -669,7 +609,6 @@ ImageBridgeChild::CreateImageClient(CompositableType aType)
TemporaryRef<ImageClient> TemporaryRef<ImageClient>
ImageBridgeChild::CreateImageClientNow(CompositableType aType) ImageBridgeChild::CreateImageClientNow(CompositableType aType)
{ {
MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
RefPtr<ImageClient> client RefPtr<ImageClient> client
= ImageClient::CreateImageClient(aType, this, TextureFlags::NO_FLAGS); = ImageClient::CreateImageClient(aType, this, TextureFlags::NO_FLAGS);
MOZ_ASSERT(client, "failed to create ImageClient"); MOZ_ASSERT(client, "failed to create ImageClient");
@ -684,7 +623,6 @@ ImageBridgeChild::AllocUnsafeShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType, ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem) ipc::Shmem* aShmem)
{ {
MOZ_ASSERT(!mShuttingDown);
if (InImageBridgeChildThread()) { if (InImageBridgeChildThread()) {
return PImageBridgeChild::AllocUnsafeShmem(aSize, aType, aShmem); return PImageBridgeChild::AllocUnsafeShmem(aSize, aType, aShmem);
} else { } else {
@ -697,7 +635,6 @@ ImageBridgeChild::AllocShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType, ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem) ipc::Shmem* aShmem)
{ {
MOZ_ASSERT(!mShuttingDown);
if (InImageBridgeChildThread()) { if (InImageBridgeChildThread()) {
return PImageBridgeChild::AllocShmem(aSize, aType, aShmem); return PImageBridgeChild::AllocShmem(aSize, aType, aShmem);
} else { } else {
@ -806,7 +743,6 @@ PTextureChild*
ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&, ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
const TextureFlags&) const TextureFlags&)
{ {
MOZ_ASSERT(!mShuttingDown);
return TextureClient::CreateIPDLActor(); return TextureClient::CreateIPDLActor();
} }
@ -843,7 +779,6 @@ PTextureChild*
ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData, ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
TextureFlags aFlags) TextureFlags aFlags)
{ {
MOZ_ASSERT(!mShuttingDown);
return SendPTextureConstructor(aSharedData, aFlags); return SendPTextureConstructor(aSharedData, aFlags);
} }
@ -851,7 +786,6 @@ void
ImageBridgeChild::RemoveTextureFromCompositable(CompositableClient* aCompositable, ImageBridgeChild::RemoveTextureFromCompositable(CompositableClient* aCompositable,
TextureClient* aTexture) TextureClient* aTexture)
{ {
MOZ_ASSERT(!mShuttingDown);
if (aTexture->GetFlags() & TextureFlags::DEALLOCATE_CLIENT) { if (aTexture->GetFlags() & TextureFlags::DEALLOCATE_CLIENT) {
mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
nullptr, aTexture->GetIPDLActor())); nullptr, aTexture->GetIPDLActor()));
@ -875,7 +809,6 @@ static void RemoveTextureSync(TextureClient* aTexture, ReentrantMonitor* aBarrie
void ImageBridgeChild::RemoveTexture(TextureClient* aTexture) void ImageBridgeChild::RemoveTexture(TextureClient* aTexture)
{ {
if (InImageBridgeChildThread()) { if (InImageBridgeChildThread()) {
MOZ_ASSERT(!mShuttingDown);
aTexture->ForceRemove(); aTexture->ForceRemove();
return; return;
} }

Просмотреть файл

@ -129,6 +129,15 @@ public:
*/ */
static bool StartUpOnThread(base::Thread* aThread); 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. * Returns true if the singleton has been created.
* *
@ -298,7 +307,6 @@ public:
void SendPendingAsyncMessge(); void SendPendingAsyncMessge();
void MarkShutDown();
protected: protected:
ImageBridgeChild(); ImageBridgeChild();
bool DispatchAllocShmemInternal(size_t aSize, bool DispatchAllocShmemInternal(size_t aSize,
@ -307,7 +315,6 @@ protected:
bool aUnsafe); bool aUnsafe);
CompositableTransaction* mTxn; CompositableTransaction* mTxn;
bool mShuttingDown;
}; };
} // layers } // layers

Просмотреть файл

@ -138,7 +138,7 @@ ImageBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess)
return bridge.get(); return bridge.get();
} }
bool ImageBridgeParent::RecvWillStop() bool ImageBridgeParent::RecvStop()
{ {
// If there is any texture still alive we have to force it to deallocate the // 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 // device data (GL textures, etc.) now because shortly after SenStop() returns
@ -153,13 +153,6 @@ bool ImageBridgeParent::RecvWillStop()
return true; 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 GenImageContainerID() {
static uint64_t sNextImageID = 1; static uint64_t sNextImageID = 1;

Просмотреть файл

@ -76,10 +76,7 @@ public:
virtual bool virtual bool
RecvChildAsyncMessages(const InfallibleTArray<AsyncChildMessageData>& aMessages) MOZ_OVERRIDE; RecvChildAsyncMessages(const InfallibleTArray<AsyncChildMessageData>& aMessages) MOZ_OVERRIDE;
// Shutdown step 1 bool RecvStop() MOZ_OVERRIDE;
virtual bool RecvWillStop() MOZ_OVERRIDE;
// Shutdown step 2
virtual bool RecvStop() MOZ_OVERRIDE;
MessageLoop * GetMessageLoop(); MessageLoop * GetMessageLoop();

Просмотреть файл

@ -36,16 +36,13 @@ parent:
sync Update(CompositableOperation[] ops) returns (EditReply[] reply); sync Update(CompositableOperation[] ops) returns (EditReply[] reply);
async UpdateNoSwap(CompositableOperation[] ops); async UpdateNoSwap(CompositableOperation[] ops);
// First step of the destruction sequence. This puts ImageBridge // First step of the destruction sequence. This puts all the ImageContainerParents
// in a state in which it can't send asynchronous messages // in a state in which they can't send asynchronous messages to their child
// so as to not race with the upcomming Stop message and destruction. // counterpart so as to not race with the upcomming __delete__ message.
// In the child side, the Stop message is not sent right after WillStop, // In the child side, the __delete__ messages are not sent right after Stop,
// it is scheduled in the ImageBridgeChild's message queue in order to ensure // they are 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 // that all the messages from the parent side have been received and processed
// before sending Stop, and that after Stop returns, there is no message in // before sending __delete__.
// flight on any side and we can safely destroy the channel and threads.
sync WillStop();
// Second step
sync Stop(); sync Stop();
sync PCompositable(TextureInfo aInfo) returns (uint64_t id); sync PCompositable(TextureInfo aInfo) returns (uint64_t id);

Просмотреть файл

@ -500,6 +500,16 @@ gfxPlatform::Shutdown()
mozilla::gl::GLContextProviderEGL::Shutdown(); mozilla::gl::GLContextProviderEGL::Shutdown();
#endif #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; delete gGfxPlatformPrefsLock;
gfxPrefs::DestroySingleton(); gfxPrefs::DestroySingleton();

Просмотреть файл

@ -14,11 +14,10 @@
#include "nsXPCOMPrivate.h" #include "nsXPCOMPrivate.h"
#include "nsXPCOMCIDInternal.h" #include "nsXPCOMCIDInternal.h"
#include "prlink.h"
#include "mozilla/layers/ImageBridgeChild.h" #include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/CompositorParent.h" #include "mozilla/layers/CompositorParent.h"
#include "mozilla/layers/AsyncTransactionTracker.h"
#include "prlink.h"
#include "nsCycleCollector.h" #include "nsCycleCollector.h"
#include "nsObserverList.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); NS_ProcessPendingEvents(thread);
mozilla::scache::StartupCache::DeleteSingleton(); mozilla::scache::StartupCache::DeleteSingleton();
if (observerService) if (observerService)