mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1187163 - Ensure we send Reset/Drain complete notifications no matter what happens in GMP{Audio,Video}Decoder. r=gerald
This commit is contained in:
parent
9aaf830c11
commit
1755d289d6
@ -28,6 +28,8 @@ GMPAudioDecoderParent::GMPAudioDecoderParent(GMPContentParent* aPlugin)
|
||||
: mIsOpen(false)
|
||||
, mShuttingDown(false)
|
||||
, mActorDestroyed(false)
|
||||
, mIsAwaitingResetComplete(false)
|
||||
, mIsAwaitingDrainComplete(false)
|
||||
, mPlugin(aPlugin)
|
||||
, mCallback(nullptr)
|
||||
{
|
||||
@ -109,6 +111,8 @@ GMPAudioDecoderParent::Reset()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mIsAwaitingResetComplete = true;
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return NS_OK;
|
||||
}
|
||||
@ -127,6 +131,8 @@ GMPAudioDecoderParent::Drain()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mIsAwaitingDrainComplete = true;
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return NS_OK;
|
||||
}
|
||||
@ -138,6 +144,11 @@ GMPAudioDecoderParent::Close()
|
||||
LOGD(("%s: %p", __FUNCTION__, this));
|
||||
MOZ_ASSERT(!mPlugin || mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
// Ensure if we've received a Close while waiting for a ResetComplete
|
||||
// or DrainComplete notification, we'll unblock the caller before processing
|
||||
// the close. This seems unlikely to happen, but better to be careful.
|
||||
UnblockResetAndDrain();
|
||||
|
||||
// Consumer is done with us; we can shut down. No more callbacks should
|
||||
// be made to mCallback. Note: do this before Shutdown()!
|
||||
mCallback = nullptr;
|
||||
@ -163,6 +174,11 @@ GMPAudioDecoderParent::Shutdown()
|
||||
}
|
||||
mShuttingDown = true;
|
||||
|
||||
// Ensure if we've received a shutdown while waiting for a ResetComplete
|
||||
// or DrainComplete notification, we'll unblock the caller before processing
|
||||
// the shutdown.
|
||||
UnblockResetAndDrain();
|
||||
|
||||
// Notify client we're gone! Won't occur after Close()
|
||||
if (mCallback) {
|
||||
mCallback->Terminated();
|
||||
@ -183,6 +199,12 @@ GMPAudioDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
mIsOpen = false;
|
||||
mActorDestroyed = true;
|
||||
|
||||
// Ensure if we've received a destroy while waiting for a ResetComplete
|
||||
// or DrainComplete notification, we'll unblock the caller before processing
|
||||
// the error.
|
||||
UnblockResetAndDrain();
|
||||
|
||||
if (mCallback) {
|
||||
// May call Close() (and Shutdown()) immediately or with a delay
|
||||
mCallback->Terminated();
|
||||
@ -230,6 +252,11 @@ GMPAudioDecoderParent::RecvDrainComplete()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mIsAwaitingDrainComplete) {
|
||||
return true;
|
||||
}
|
||||
mIsAwaitingDrainComplete = false;
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mCallback->DrainComplete();
|
||||
|
||||
@ -243,6 +270,11 @@ GMPAudioDecoderParent::RecvResetComplete()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mIsAwaitingResetComplete) {
|
||||
return true;
|
||||
}
|
||||
mIsAwaitingResetComplete = false;
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mCallback->ResetComplete();
|
||||
|
||||
@ -256,6 +288,11 @@ GMPAudioDecoderParent::RecvError(const GMPErr& aError)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure if we've received an error while waiting for a ResetComplete
|
||||
// or DrainComplete notification, we'll unblock the caller before processing
|
||||
// the error.
|
||||
UnblockResetAndDrain();
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mCallback->Error(aError);
|
||||
|
||||
@ -281,5 +318,23 @@ GMPAudioDecoderParent::Recv__delete__()
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GMPAudioDecoderParent::UnblockResetAndDrain()
|
||||
{
|
||||
if (!mCallback) {
|
||||
MOZ_ASSERT(!mIsAwaitingResetComplete);
|
||||
MOZ_ASSERT(!mIsAwaitingDrainComplete);
|
||||
return;
|
||||
}
|
||||
if (mIsAwaitingResetComplete) {
|
||||
mIsAwaitingResetComplete = false;
|
||||
mCallback->ResetComplete();
|
||||
}
|
||||
if (mIsAwaitingDrainComplete) {
|
||||
mIsAwaitingDrainComplete = false;
|
||||
mCallback->DrainComplete();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
@ -53,9 +53,13 @@ private:
|
||||
virtual bool RecvShutdown() override;
|
||||
virtual bool Recv__delete__() override;
|
||||
|
||||
void UnblockResetAndDrain();
|
||||
|
||||
bool mIsOpen;
|
||||
bool mShuttingDown;
|
||||
bool mActorDestroyed;
|
||||
bool mIsAwaitingResetComplete;
|
||||
bool mIsAwaitingDrainComplete;
|
||||
nsRefPtr<GMPContentParent> mPlugin;
|
||||
GMPAudioDecoderCallbackProxy* mCallback;
|
||||
};
|
||||
|
@ -43,6 +43,8 @@ GMPVideoDecoderParent::GMPVideoDecoderParent(GMPContentParent* aPlugin)
|
||||
, mIsOpen(false)
|
||||
, mShuttingDown(false)
|
||||
, mActorDestroyed(false)
|
||||
, mIsAwaitingResetComplete(false)
|
||||
, mIsAwaitingDrainComplete(false)
|
||||
, mPlugin(aPlugin)
|
||||
, mCallback(nullptr)
|
||||
, mVideoHost(this)
|
||||
@ -67,6 +69,12 @@ GMPVideoDecoderParent::Close()
|
||||
{
|
||||
LOGD(("%s: %p", __FUNCTION__, this));
|
||||
MOZ_ASSERT(!mPlugin || mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
// Ensure if we've received a Close while waiting for a ResetComplete
|
||||
// or DrainComplete notification, we'll unblock the caller before processing
|
||||
// the close. This seems unlikely to happen, but better to be careful.
|
||||
UnblockResetAndDrain();
|
||||
|
||||
// Consumer is done with us; we can shut down. No more callbacks should
|
||||
// be made to mCallback. Note: do this before Shutdown()!
|
||||
mCallback = nullptr;
|
||||
@ -161,6 +169,8 @@ GMPVideoDecoderParent::Reset()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mIsAwaitingResetComplete = true;
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return NS_OK;
|
||||
}
|
||||
@ -179,6 +189,8 @@ GMPVideoDecoderParent::Drain()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mIsAwaitingDrainComplete = true;
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return NS_OK;
|
||||
}
|
||||
@ -207,6 +219,11 @@ GMPVideoDecoderParent::Shutdown()
|
||||
}
|
||||
mShuttingDown = true;
|
||||
|
||||
// Ensure if we've received a shutdown while waiting for a ResetComplete
|
||||
// or DrainComplete notification, we'll unblock the caller before processing
|
||||
// the shutdown.
|
||||
UnblockResetAndDrain();
|
||||
|
||||
// Notify client we're gone! Won't occur after Close()
|
||||
if (mCallback) {
|
||||
mCallback->Terminated();
|
||||
@ -229,6 +246,11 @@ GMPVideoDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
mActorDestroyed = true;
|
||||
mVideoHost.DoneWithAPI();
|
||||
|
||||
// Ensure if we've received a destroy while waiting for a ResetComplete
|
||||
// or DrainComplete notification, we'll unblock the caller before processing
|
||||
// the error.
|
||||
UnblockResetAndDrain();
|
||||
|
||||
if (mCallback) {
|
||||
// May call Close() (and Shutdown()) immediately or with a delay
|
||||
mCallback->Terminated();
|
||||
@ -307,6 +329,11 @@ GMPVideoDecoderParent::RecvDrainComplete()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mIsAwaitingDrainComplete) {
|
||||
return true;
|
||||
}
|
||||
mIsAwaitingDrainComplete = false;
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mCallback->DrainComplete();
|
||||
|
||||
@ -320,6 +347,11 @@ GMPVideoDecoderParent::RecvResetComplete()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mIsAwaitingResetComplete) {
|
||||
return true;
|
||||
}
|
||||
mIsAwaitingResetComplete = false;
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mCallback->ResetComplete();
|
||||
|
||||
@ -333,6 +365,11 @@ GMPVideoDecoderParent::RecvError(const GMPErr& aError)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure if we've received an error while waiting for a ResetComplete
|
||||
// or DrainComplete notification, we'll unblock the caller before processing
|
||||
// the error.
|
||||
UnblockResetAndDrain();
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mCallback->Error(aError);
|
||||
|
||||
@ -387,5 +424,23 @@ GMPVideoDecoderParent::Recv__delete__()
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoDecoderParent::UnblockResetAndDrain()
|
||||
{
|
||||
if (!mCallback) {
|
||||
MOZ_ASSERT(!mIsAwaitingResetComplete);
|
||||
MOZ_ASSERT(!mIsAwaitingDrainComplete);
|
||||
return;
|
||||
}
|
||||
if (mIsAwaitingResetComplete) {
|
||||
mIsAwaitingResetComplete = false;
|
||||
mCallback->ResetComplete();
|
||||
}
|
||||
if (mIsAwaitingDrainComplete) {
|
||||
mIsAwaitingDrainComplete = false;
|
||||
mCallback->DrainComplete();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
@ -79,9 +79,13 @@ private:
|
||||
Shmem* aMem) override;
|
||||
virtual bool Recv__delete__() override;
|
||||
|
||||
void UnblockResetAndDrain();
|
||||
|
||||
bool mIsOpen;
|
||||
bool mShuttingDown;
|
||||
bool mActorDestroyed;
|
||||
bool mIsAwaitingResetComplete;
|
||||
bool mIsAwaitingDrainComplete;
|
||||
nsRefPtr<GMPContentParent> mPlugin;
|
||||
GMPVideoDecoderCallbackProxy* mCallback;
|
||||
GMPVideoHostImpl mVideoHost;
|
||||
|
Loading…
Reference in New Issue
Block a user