Backed out changesets 74ef5120ae2f and d26dfd37031a (bug 924622) for frequent Android and OSX crashes.

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2014-04-30 13:21:07 -04:00
parent 96ef7ff235
commit 4d3f585310
8 changed files with 59 additions and 122 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 958889 moves files into the new mobile/android/base/tabspanel/ package.
Bug 852935 - Android builds aren't picking up the Gamepad WebIDL changes.

View File

@ -166,43 +166,26 @@ static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton;
static Thread *sImageBridgeChildThread = 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<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.
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;
@ -267,7 +250,6 @@ static void ConnectImageBridge(ImageBridgeChild * child, ImageBridgeParent * par
}
ImageBridgeChild::ImageBridgeChild()
: mShuttingDown(false)
{
mTxn = new CompositableTransaction();
}
@ -276,18 +258,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);
@ -298,7 +272,6 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable)
PCompositableChild*
ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID)
{
MOZ_ASSERT(!mShuttingDown);
return CompositableClient::CreateIPDLActor();
}
@ -362,17 +335,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));
@ -387,17 +349,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));
@ -417,10 +368,6 @@ static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContaine
void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient,
ImageContainer* aContainer)
{
if (!IsCreated()) {
return;
}
if (InImageBridgeChildThread()) {
UpdateImageClientNow(aClient, aContainer);
return;
@ -445,10 +392,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;
@ -473,7 +416,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();
@ -486,7 +428,6 @@ void ImageBridgeChild::FlushAllImagesNow(ImageClient* aClient, ImageContainer* a
void
ImageBridgeChild::BeginTransaction()
{
MOZ_ASSERT(!mShuttingDown);
MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?");
mTxn->Begin();
}
@ -508,7 +449,6 @@ private:
void
ImageBridgeChild::EndTransaction()
{
MOZ_ASSERT(!mShuttingDown);
MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?");
AutoEndTransaction _(mTxn);
@ -602,27 +542,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("ImageBridgeDestroyTask lock");
ReentrantMonitorAutoEnter autoMon(barrier);
bool done = false;
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
NewRunnableFunction(&ImageBridgeShutdownStep1, &barrier, &done));
while (!done) {
barrier.Wait();
}
done = false;
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
NewRunnableFunction(&ImageBridgeShutdownStep2, &barrier, &done));
while (!done) {
barrier.Wait();
}
ImageBridgeChild::DestroyBridge();
delete sImageBridgeChildThread;
sImageBridgeChildThread = nullptr;
}
@ -646,6 +568,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() &&
@ -695,7 +646,6 @@ ImageBridgeChild::CreateImageClient(CompositableType aType)
TemporaryRef<ImageClient>
ImageBridgeChild::CreateImageClientNow(CompositableType aType)
{
MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
RefPtr<ImageClient> client
= ImageClient::CreateImageClient(aType, this, TextureFlags::NO_FLAGS);
MOZ_ASSERT(client, "failed to create ImageClient");
@ -709,7 +659,6 @@ PGrallocBufferChild*
ImageBridgeChild::AllocPGrallocBufferChild(const IntSize&, const uint32_t&, const uint32_t&,
MaybeMagicGrallocBufferHandle*)
{
MOZ_ASSERT(!mShuttingDown);
#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
return GrallocBufferActor::Create();
#else
@ -735,7 +684,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 {
@ -748,7 +696,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 {
@ -888,7 +835,6 @@ ImageBridgeChild::AllocGrallocBufferNow(const gfx::IntSize& aSize,
MaybeMagicGrallocBufferHandle* aHandle,
PGrallocBufferChild** aChild)
{
MOZ_ASSERT(!mShuttingDown);
#ifdef MOZ_WIDGET_GONK
*aChild = SendPGrallocBufferConstructor(aSize,
aFormat,
@ -951,7 +897,6 @@ PTextureChild*
ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
const TextureFlags&)
{
MOZ_ASSERT(!mShuttingDown);
return TextureClient::CreateIPDLActor();
}
@ -965,7 +910,6 @@ PTextureChild*
ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
TextureFlags aFlags)
{
MOZ_ASSERT(!mShuttingDown);
return SendPTextureConstructor(aSharedData, aFlags);
}
@ -973,7 +917,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()));
@ -997,7 +940,6 @@ static void RemoveTextureSync(TextureClient* aTexture, ReentrantMonitor* aBarrie
void ImageBridgeChild::RemoveTexture(TextureClient* aTexture)
{
if (InImageBridgeChildThread()) {
MOZ_ASSERT(!mShuttingDown);
aTexture->ForceRemove();
return;
}

View File

@ -130,6 +130,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.
*
@ -305,7 +314,6 @@ public:
uint32_t aFormat, uint32_t aUsage,
MaybeMagicGrallocBufferHandle* aHandle,
PGrallocBufferChild** aChild);
void MarkShutDown();
protected:
ImageBridgeChild();
bool DispatchAllocShmemInternal(size_t aSize,
@ -321,8 +329,6 @@ protected:
MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE;
virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild) MOZ_OVERRIDE;
bool mShuttingDown;
};
} // layers

View File

@ -139,7 +139,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
@ -154,13 +154,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;

View File

@ -70,10 +70,7 @@ public:
const TextureFlags& aFlags) MOZ_OVERRIDE;
virtual bool DeallocPTextureParent(PTextureParent* actor) MOZ_OVERRIDE;
// Shutdown step 1
virtual bool RecvWillStop() MOZ_OVERRIDE;
// Shutdown step 2
virtual bool RecvStop() MOZ_OVERRIDE;
bool RecvStop() MOZ_OVERRIDE;
MessageLoop * GetMessageLoop();

View File

@ -42,15 +42,13 @@ parent:
sync PGrallocBuffer(IntSize size, uint32_t format, uint32_t usage)
returns (MaybeMagicGrallocBufferHandle handle);
// 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();
// 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);

View File

@ -493,6 +493,12 @@ gfxPlatform::Shutdown()
mozilla::gl::GLContextProviderEGL::Shutdown();
#endif
// This will block this thread untill the ImageBridge protocol is completely
// deleted.
ImageBridgeChild::ShutDown();
CompositorParent::ShutDown();
delete gGfxPlatformPrefsLock;
gfxPrefs::DestroySingleton();

View File

@ -789,11 +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.
mozilla::layers::ImageBridgeChild::ShutDown();
mozilla::layers::CompositorParent::ShutDown();
NS_ProcessPendingEvents(thread);
mozilla::scache::StartupCache::DeleteSingleton();
if (observerService)