Destoy TextureData even if TextureChild::ActorDestroy has already run. (bug 1303426 part 4, r=nical)

--HG--
extra : rebase_source : 8ca1eb13ac949ecf00efe821acd3fbde8cc11c7e
This commit is contained in:
David Anderson 2016-09-21 22:40:21 -07:00
Родитель 2255e55899
Коммит c77a418e0d
1 изменённых файлов: 44 добавлений и 33 удалений

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

@ -150,14 +150,14 @@ private:
///
/// This will asynchronously send a Destroy message to the parent actor, whom
/// will send the delete message.
void Destroy(CompositableForwarder* aFwd);
void Destroy(const TextureDeallocParams& aParams);
/// The ugly and slow way to destroy the actor.
///
/// This will block until the Parent actor has handled the Destroy message,
/// and then start the asynchronous handshake (and destruction will already
/// be done on the parent side, when the async part happens).
void DestroySynchronously(CompositableForwarder* aFwd);
void DestroySynchronously(const TextureDeallocParams& aParams);
// This lock is used order to prevent several threads to access the
// TextureClient's data concurrently. In particular, it prevents shutdown
@ -275,28 +275,53 @@ TextureChild::ActorDestroy(ActorDestroyReason why)
}
void
TextureChild::Destroy(CompositableForwarder* aFwd)
TextureChild::Destroy(const TextureDeallocParams& aParams)
{
MOZ_ASSERT(!mOwnerCalledDestroy);
if (!mOwnerCalledDestroy) {
mOwnerCalledDestroy = true;
if (!aFwd || !aFwd->DestroyInTransaction(this, false)) {
this->SendDestroy();
}
if (mOwnerCalledDestroy) {
return;
}
mOwnerCalledDestroy = true;
// DestroyTextureData will be called by TextureChild::ActorDestroy
mTextureData = aParams.data;
mOwnsTextureData = aParams.clientDeallocation;
if (!mCompositableForwarder ||
!mCompositableForwarder->DestroyInTransaction(this, false))
{
this->SendDestroy();
}
}
void
TextureChild::DestroySynchronously(CompositableForwarder* aFwd)
TextureChild::DestroySynchronously(const TextureDeallocParams& aParams)
{
MOZ_PERFORMANCE_WARNING("gfx", "IPDL actor requires synchronous deallocation");
MOZ_PERFORMANCE_WARNING("gfx", "TextureClient/Host pair requires synchronous deallocation");
MOZ_ASSERT(!mOwnerCalledDestroy);
if (!mOwnerCalledDestroy) {
mOwnerCalledDestroy = true;
if (!aFwd || !aFwd->DestroyInTransaction(this, true)) {
this->SendDestroySync();
this->SendDestroy();
}
if (mOwnerCalledDestroy) {
return;
}
mOwnerCalledDestroy = true;
DestroyTextureData(
aParams.data,
aParams.allocator,
aParams.clientDeallocation,
mMainThreadOnly);
if (!IPCOpen()) {
return;
}
if (!mCompositableForwarder ||
!mCompositableForwarder->DestroyInTransaction(this, true))
{
this->SendDestroySync();
this->SendDestroy();
}
}
@ -381,24 +406,10 @@ DeallocateTextureClient(TextureDeallocParams params)
return;
}
if (!actor->IPCOpen()) {
// The actor is already deallocated which probably means there was a shutdown
// race causing this function to be called concurrently which is bad!
gfxCriticalError() << "Racy texture deallocation";
return;
}
if (params.syncDeallocation) {
MOZ_PERFORMANCE_WARNING("gfx",
"TextureClient/Host pair requires synchronous deallocation");
actor->DestroySynchronously(actor->mCompositableForwarder);
DestroyTextureData(params.data, params.allocator, params.clientDeallocation,
actor->mMainThreadOnly);
if (params.syncDeallocation || !actor->IPCOpen()) {
actor->DestroySynchronously(params);
} else {
actor->mTextureData = params.data;
actor->mOwnsTextureData = params.clientDeallocation;
actor->Destroy(actor->mCompositableForwarder);
// DestroyTextureData will be called by TextureChild::ActorDestroy
actor->Destroy(params);
}
}