Bug 1245789 - Add abstract thread wrapper for the GMP thread. r=gerald

I need to make GMPParent::Init() async, because the WebIDL JSON parsing
must happen on the main thread, and GMPParent::Init() is called on the
GMP thread, so I need GMPParent::Init() to be async so that in the
Chrome manifest case it can dispatch a task to the main thread to parse
the Chrome manifest before completing. So I'll make GMPParent::Init()
return a promise, and to do that, I need the GMP thread to have an
AbstractThread wrapper.

MozReview-Commit-ID: 44b4Z4jpar8
This commit is contained in:
Chris Pearce 2016-04-12 16:12:20 +12:00
Родитель e52ed67d48
Коммит 67f4ed3368
6 изменённых файлов: 40 добавлений и 32 удалений

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

@ -357,6 +357,8 @@ GeckoMediaPluginService::GetThread(nsIThread** aThread)
return rv;
}
mAbstractGMPThread = CreateXPCOMAbstractThreadWrapper(mGMPThread, false);
// Tell the thread to initialize plugins
InitializePlugins();
}
@ -367,6 +369,12 @@ GeckoMediaPluginService::GetThread(nsIThread** aThread)
return NS_OK;
}
RefPtr<AbstractThread>
GeckoMediaPluginService::GetAbstractGMPThread()
{
return mAbstractGMPThread;
}
class GetGMPContentParentForAudioDecoderDone : public GetGMPContentParentCallback
{
public:

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

@ -19,6 +19,7 @@
#include "nsPIDOMWindow.h"
#include "nsIDocument.h"
#include "nsIWeakReference.h"
#include "mozilla/AbstractThread.h"
template <class> struct already_AddRefed;
@ -74,6 +75,8 @@ public:
void AddPluginCrashedEventTarget(const uint32_t aPluginId,
nsPIDOMWindowInner* aParentWindow);
RefPtr<AbstractThread> GetAbstractGMPThread();
protected:
GeckoMediaPluginService();
virtual ~GeckoMediaPluginService();
@ -92,6 +95,7 @@ protected:
Mutex mMutex; // Protects mGMPThread and mGMPThreadShutdown and some members
// in derived classes.
nsCOMPtr<nsIThread> mGMPThread;
RefPtr<AbstractThread> mAbstractGMPThread;
bool mGMPThreadShutdown;
bool mShuttingDownOnGMPThread;

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

@ -161,8 +161,11 @@ private:
class EMEMediaDataDecoderProxy : public MediaDataDecoderProxy {
public:
EMEMediaDataDecoderProxy(nsIThread* aProxyThread, MediaDataDecoderCallback* aCallback, CDMProxy* aProxy, FlushableTaskQueue* aTaskQueue)
: MediaDataDecoderProxy(aProxyThread, aCallback)
EMEMediaDataDecoderProxy(already_AddRefed<AbstractThread> aProxyThread,
MediaDataDecoderCallback* aCallback,
CDMProxy* aProxy,
FlushableTaskQueue* aTaskQueue)
: MediaDataDecoderProxy(Move(aProxyThread), aCallback)
, mSamplesWaitingForKey(new SamplesWaitingForKey(this, aTaskQueue, aProxy))
, mProxy(aProxy)
{
@ -220,18 +223,16 @@ EMEDecoderModule::~EMEDecoderModule()
static already_AddRefed<MediaDataDecoderProxy>
CreateDecoderWrapper(MediaDataDecoderCallback* aCallback, CDMProxy* aProxy, FlushableTaskQueue* aTaskQueue)
{
nsCOMPtr<mozIGeckoMediaPluginService> gmpService = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
if (!gmpService) {
RefPtr<gmp::GeckoMediaPluginService> s(gmp::GeckoMediaPluginService::GetGeckoMediaPluginService());
if (!s) {
return nullptr;
}
nsCOMPtr<nsIThread> thread;
nsresult rv = gmpService->GetThread(getter_AddRefs(thread));
if (NS_FAILED(rv)) {
RefPtr<AbstractThread> thread(s->GetAbstractGMPThread());
if (!thread) {
return nullptr;
}
RefPtr<MediaDataDecoderProxy> decoder(new EMEMediaDataDecoderProxy(thread, aCallback, aProxy, aTaskQueue));
RefPtr<MediaDataDecoderProxy> decoder(
new EMEMediaDataDecoderProxy(thread.forget(), aCallback, aProxy, aTaskQueue));
return decoder.forget();
}

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

@ -31,18 +31,15 @@ GMPDecoderModule::~GMPDecoderModule()
static already_AddRefed<MediaDataDecoderProxy>
CreateDecoderWrapper(MediaDataDecoderCallback* aCallback)
{
nsCOMPtr<mozIGeckoMediaPluginService> gmpService = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
if (!gmpService) {
RefPtr<gmp::GeckoMediaPluginService> s(gmp::GeckoMediaPluginService::GetGeckoMediaPluginService());
if (!s) {
return nullptr;
}
nsCOMPtr<nsIThread> thread;
nsresult rv = gmpService->GetThread(getter_AddRefs(thread));
if (NS_FAILED(rv)) {
RefPtr<AbstractThread> thread(s->GetAbstractGMPThread());
if (!thread) {
return nullptr;
}
RefPtr<MediaDataDecoderProxy> decoder(new MediaDataDecoderProxy(thread, aCallback));
RefPtr<MediaDataDecoderProxy> decoder(new MediaDataDecoderProxy(thread.forget(), aCallback));
return decoder.forget();
}

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

@ -34,7 +34,7 @@ MediaDataDecoderProxy::Init()
{
MOZ_ASSERT(!mIsShutdown);
return InvokeAsync(mProxyThreadWrapper, this, __func__,
return InvokeAsync(mProxyThread, this, __func__,
&MediaDataDecoderProxy::InternalInit);
}
@ -45,8 +45,7 @@ MediaDataDecoderProxy::Input(MediaRawData* aSample)
MOZ_ASSERT(!mIsShutdown);
nsCOMPtr<nsIRunnable> task(new InputTask(mProxyDecoder, aSample));
nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
mProxyThread->Dispatch(task.forget());
return NS_OK;
}
@ -61,8 +60,7 @@ MediaDataDecoderProxy::Flush()
nsCOMPtr<nsIRunnable> task;
task = NS_NewRunnableMethod(mProxyDecoder, &MediaDataDecoder::Flush);
nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
mProxyThread->Dispatch(task.forget());
mFlushComplete.WaitUntil(true);
@ -77,8 +75,7 @@ MediaDataDecoderProxy::Drain()
nsCOMPtr<nsIRunnable> task;
task = NS_NewRunnableMethod(mProxyDecoder, &MediaDataDecoder::Drain);
nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
mProxyThread->Dispatch(task.forget());
return NS_OK;
}
@ -92,7 +89,7 @@ MediaDataDecoderProxy::Shutdown()
#endif
nsCOMPtr<nsIRunnable> task;
task = NS_NewRunnableMethod(mProxyDecoder, &MediaDataDecoder::Shutdown);
nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_SYNC);
nsresult rv = mProxyThread->AsXPCOMThread()->Dispatch(task, NS_DISPATCH_SYNC);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}

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

@ -11,6 +11,7 @@
#include "mozilla/RefPtr.h"
#include "nsThreadUtils.h"
#include "nscore.h"
#include "GMPService.h"
namespace mozilla {
@ -62,7 +63,8 @@ class MediaDataDecoderProxy;
class MediaDataDecoderCallbackProxy : public MediaDataDecoderCallback {
public:
MediaDataDecoderCallbackProxy(MediaDataDecoderProxy* aProxyDecoder, MediaDataDecoderCallback* aCallback)
MediaDataDecoderCallbackProxy(MediaDataDecoderProxy* aProxyDecoder,
MediaDataDecoderCallback* aCallback)
: mProxyDecoder(aProxyDecoder)
, mProxyCallback(aCallback)
{
@ -100,7 +102,8 @@ private:
class MediaDataDecoderProxy : public MediaDataDecoder {
public:
MediaDataDecoderProxy(nsIThread* aProxyThread, MediaDataDecoderCallback* aCallback)
MediaDataDecoderProxy(already_AddRefed<AbstractThread> aProxyThread,
MediaDataDecoderCallback* aCallback)
: mProxyThread(aProxyThread)
, mProxyCallback(this, aCallback)
, mFlushComplete(false)
@ -108,7 +111,6 @@ public:
, mIsShutdown(false)
#endif
{
mProxyThreadWrapper = CreateXPCOMAbstractThreadWrapper(aProxyThread, false);
}
// Ideally, this would return a regular MediaDataDecoderCallback pointer
@ -151,7 +153,7 @@ private:
#ifdef DEBUG
bool IsOnProxyThread() {
return NS_GetCurrentThread() == mProxyThread;
return mProxyThread && mProxyThread->IsCurrentThreadIn();
}
#endif
@ -159,8 +161,7 @@ private:
friend class InitTask;
RefPtr<MediaDataDecoder> mProxyDecoder;
nsCOMPtr<nsIThread> mProxyThread;
RefPtr<AbstractThread> mProxyThreadWrapper;
RefPtr<AbstractThread> mProxyThread;
MediaDataDecoderCallbackProxy mProxyCallback;