Bug 737437 - Post a task to handle compositor destruction. r=bgirard

This commit is contained in:
Ali Juma 2012-03-30 15:43:11 -04:00
parent 96c73034b8
commit 34cf50ec43
4 changed files with 45 additions and 5 deletions

View File

@ -78,14 +78,24 @@ CompositorParent::Destroy()
NS_ABORT_IF_FALSE(ManagedPLayersParent().Length() == 0,
"CompositorParent destroyed before managed PLayersParent");
// Ensure that the layer manager is destroyed on the compositor thread.
// Ensure that the layer manager is destructed on the compositor thread.
mLayerManager = NULL;
}
bool
CompositorParent::RecvWillStop()
{
mPaused = true;
// Ensure that the layer manager is destroyed before CompositorChild.
mLayerManager->Destroy();
return true;
}
bool
CompositorParent::RecvStop()
{
mPaused = true;
Destroy();
return true;
}

View File

@ -93,6 +93,7 @@ public:
CompositorParent(nsIWidget* aWidget, base::Thread* aCompositorThread);
virtual ~CompositorParent();
virtual bool RecvWillStop() MOZ_OVERRIDE;
virtual bool RecvStop() MOZ_OVERRIDE;
virtual bool RecvPause() MOZ_OVERRIDE;
virtual bool RecvResume() MOZ_OVERRIDE;

View File

@ -61,7 +61,10 @@ rpc protocol PCompositor
parent:
// Clean up in preparation for destruction.
// The child is about to be destroyed, so perform any necessary cleanup.
sync WillStop();
// Clean up in preparation for own destruction.
sync Stop();
// Pause/resume the compositor. These are intended to be used on mobile, when

View File

@ -135,6 +135,17 @@ nsBaseWidget::nsBaseWidget()
}
static void DestroyCompositor(CompositorParent* aCompositorParent,
CompositorChild* aCompositorChild,
Thread* aCompositorThread)
{
aCompositorChild->Destroy();
delete aCompositorThread;
aCompositorParent->Release();
aCompositorChild->Release();
}
//-------------------------------------------------------------------------
//
// nsBaseWidget destructor
@ -153,8 +164,23 @@ nsBaseWidget::~nsBaseWidget()
}
if (mCompositorChild) {
mCompositorChild->Destroy();
delete mCompositorThread;
mCompositorChild->SendWillStop();
// The call just made to SendWillStop can result in IPC from the
// CompositorParent to the CompositorChild (e.g. caused by the destruction
// of shared memory). We need to ensure this gets processed by the
// CompositorChild before it gets destroyed. It suffices to ensure that
// events already in the MessageLoop get processed before the
// CompositorChild is destroyed, so we add a task to the MessageLoop to
// handle compositor desctruction.
MessageLoop::current()->
PostTask(FROM_HERE,
NewRunnableFunction(DestroyCompositor, mCompositorParent,
mCompositorChild, mCompositorThread));
// The DestroyCompositor task we just added to the MessageLoop will handle
// releasing mCompositorParent and mCompositorChild.
mCompositorParent.forget();
mCompositorChild.forget();
}
#ifdef NOISY_WIDGET_LEAKS