Bug 1204622 - release codec listener at reader task queue. r=jya

--HG--
extra : rebase_source : adb41147997f51941746af1f8dfe151f784c1771
This commit is contained in:
Alfredo Yang 2015-10-01 00:43:00 +02:00
Родитель 2aa965ccb5
Коммит d66d46126b
3 изменённых файлов: 45 добавлений и 4 удалений

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

@ -61,7 +61,12 @@ GonkMediaDataDecoder::Init()
nsresult
GonkMediaDataDecoder::Shutdown()
{
return mManager->Shutdown();
nsresult rv = mManager->Shutdown();
// Because codec allocated runnable and init promise is at reader TaskQueue,
// so manager needs to be destroyed at reader TaskQueue to prevent racing.
mManager = nullptr;
return rv;
}
// Inserts data into the decoder's pipeline.

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

@ -71,6 +71,7 @@ GonkVideoDecoderManager::GonkVideoDecoderManager(
GonkVideoDecoderManager::~GonkVideoDecoderManager()
{
mVideoListener->NotifyManagerRelease();
MOZ_COUNT_DTOR(GonkVideoDecoderManager);
}
@ -563,10 +564,25 @@ GonkVideoDecoderManager::VideoResourceListener::~VideoResourceListener()
void
GonkVideoDecoderManager::VideoResourceListener::codecReserved()
{
// This class holds VideoResourceListener reference to prevent it's destroyed.
class CodecListenerHolder : public nsRunnable {
public:
CodecListenerHolder(VideoResourceListener* aListener)
: mVideoListener(aListener) {}
NS_IMETHOD Run()
{
mVideoListener->NotifyCodecReserved();
mVideoListener = nullptr;
return NS_OK;
}
android::sp<VideoResourceListener> mVideoListener;
};
if (mManager) {
nsCOMPtr<nsIRunnable> r =
NS_NewNonOwningRunnableMethod(mManager, &GonkVideoDecoderManager::codecReserved);
mManager->mReaderTaskQueue->Dispatch(r.forget());
nsRefPtr<CodecListenerHolder> runner = new CodecListenerHolder(this);
mManager->mReaderTaskQueue->Dispatch(runner.forget());
}
}
@ -574,12 +590,29 @@ void
GonkVideoDecoderManager::VideoResourceListener::codecCanceled()
{
if (mManager) {
MOZ_ASSERT(mManager->mReaderTaskQueue->IsCurrentThreadIn());
nsCOMPtr<nsIRunnable> r =
NS_NewNonOwningRunnableMethod(mManager, &GonkVideoDecoderManager::codecCanceled);
mManager->mReaderTaskQueue->Dispatch(r.forget());
}
}
void
GonkVideoDecoderManager::VideoResourceListener::NotifyManagerRelease()
{
MOZ_ASSERT_IF(mManager, mManager->mReaderTaskQueue->IsCurrentThreadIn());
mManager = nullptr;
}
void
GonkVideoDecoderManager::VideoResourceListener::NotifyCodecReserved()
{
if (mManager) {
MOZ_ASSERT(mManager->mReaderTaskQueue->IsCurrentThreadIn());
mManager->codecReserved();
}
}
uint8_t *
GonkVideoDecoderManager::GetColorConverterBuffer(int32_t aWidth, int32_t aHeight)
{

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

@ -97,6 +97,9 @@ private:
void codecReserved() override;
void codecCanceled() override;
void NotifyManagerRelease();
void NotifyCodecReserved();
private:
// Forbidden
VideoResourceListener() = delete;