mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
12f0323d62
Backed out changeset f0b20e3db93c (bug 1020760) Backed out changeset 412b654e5cd2 (bug 1035653) Backed out changeset 01ba0892af29 (bug 1020760) Backed out changeset c7de1f4b078f (bug 1020760) Backed out changeset 96aa9d33a1f5 (bug 1020090)
217 lines
3.7 KiB
C++
217 lines
3.7 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "GMPPlatform.h"
|
|
#include "mozilla/Monitor.h"
|
|
#include "nsAutoPtr.h"
|
|
|
|
namespace mozilla {
|
|
namespace gmp {
|
|
|
|
static MessageLoop* sMainLoop = nullptr;
|
|
|
|
// We just need a refcounted wrapper for GMPTask objects.
|
|
class Runnable MOZ_FINAL
|
|
{
|
|
public:
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Runnable)
|
|
|
|
Runnable(GMPTask* aTask)
|
|
: mTask(aTask)
|
|
{
|
|
MOZ_ASSERT(mTask);
|
|
}
|
|
|
|
void Run()
|
|
{
|
|
mTask->Run();
|
|
mTask = nullptr;
|
|
}
|
|
|
|
private:
|
|
~Runnable()
|
|
{
|
|
}
|
|
|
|
nsAutoPtr<GMPTask> mTask;
|
|
};
|
|
|
|
class SyncRunnable MOZ_FINAL
|
|
{
|
|
public:
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SyncRunnable)
|
|
|
|
SyncRunnable(GMPTask* aTask, MessageLoop* aMessageLoop)
|
|
: mDone(false)
|
|
, mTask(aTask)
|
|
, mMessageLoop(aMessageLoop)
|
|
, mMonitor("GMPSyncRunnable")
|
|
{
|
|
MOZ_ASSERT(mTask);
|
|
MOZ_ASSERT(mMessageLoop);
|
|
}
|
|
|
|
void Post()
|
|
{
|
|
// We assert here for two reasons.
|
|
// 1) Nobody should be blocking the main thread.
|
|
// 2) This prevents deadlocks when doing sync calls to main which if the
|
|
// main thread tries to do a sync call back to the calling thread.
|
|
MOZ_ASSERT(MessageLoop::current() != sMainLoop);
|
|
|
|
mMessageLoop->PostTask(FROM_HERE, NewRunnableMethod(this, &SyncRunnable::Run));
|
|
MonitorAutoLock lock(mMonitor);
|
|
while (!mDone) {
|
|
lock.Wait();
|
|
}
|
|
}
|
|
|
|
void Run()
|
|
{
|
|
mTask->Run();
|
|
mTask = nullptr;
|
|
MonitorAutoLock lock(mMonitor);
|
|
mDone = true;
|
|
lock.Notify();
|
|
}
|
|
|
|
private:
|
|
~SyncRunnable()
|
|
{
|
|
}
|
|
|
|
bool mDone;
|
|
nsAutoPtr<GMPTask> mTask;
|
|
MessageLoop* mMessageLoop;
|
|
Monitor mMonitor;
|
|
};
|
|
|
|
GMPErr
|
|
CreateThread(GMPThread** aThread)
|
|
{
|
|
if (!aThread) {
|
|
return GMPGenericErr;
|
|
}
|
|
|
|
*aThread = new GMPThreadImpl();
|
|
|
|
return GMPNoErr;
|
|
}
|
|
|
|
GMPErr
|
|
RunOnMainThread(GMPTask* aTask)
|
|
{
|
|
if (!aTask || !sMainLoop) {
|
|
return GMPGenericErr;
|
|
}
|
|
|
|
nsRefPtr<Runnable> r = new Runnable(aTask);
|
|
|
|
sMainLoop->PostTask(FROM_HERE, NewRunnableMethod(r.get(), &Runnable::Run));
|
|
|
|
return GMPNoErr;
|
|
}
|
|
|
|
GMPErr
|
|
SyncRunOnMainThread(GMPTask* aTask)
|
|
{
|
|
if (!aTask || !sMainLoop || sMainLoop == MessageLoop::current()) {
|
|
return GMPGenericErr;
|
|
}
|
|
|
|
nsRefPtr<SyncRunnable> r = new SyncRunnable(aTask, sMainLoop);
|
|
|
|
r->Post();
|
|
|
|
return GMPNoErr;
|
|
}
|
|
|
|
GMPErr
|
|
CreateMutex(GMPMutex** aMutex)
|
|
{
|
|
if (!aMutex) {
|
|
return GMPGenericErr;
|
|
}
|
|
|
|
*aMutex = new GMPMutexImpl();
|
|
|
|
return GMPNoErr;
|
|
}
|
|
|
|
void
|
|
InitPlatformAPI(GMPPlatformAPI& aPlatformAPI)
|
|
{
|
|
if (!sMainLoop) {
|
|
sMainLoop = MessageLoop::current();
|
|
}
|
|
|
|
aPlatformAPI.version = 0;
|
|
aPlatformAPI.createthread = &CreateThread;
|
|
aPlatformAPI.runonmainthread = &RunOnMainThread;
|
|
aPlatformAPI.syncrunonmainthread = &SyncRunOnMainThread;
|
|
aPlatformAPI.createmutex = &CreateMutex;
|
|
}
|
|
|
|
GMPThreadImpl::GMPThreadImpl()
|
|
: mMutex("GMPThreadImpl"),
|
|
mThread("GMPThread")
|
|
{
|
|
}
|
|
|
|
GMPThreadImpl::~GMPThreadImpl()
|
|
{
|
|
}
|
|
|
|
void
|
|
GMPThreadImpl::Post(GMPTask* aTask)
|
|
{
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
if (!mThread.IsRunning()) {
|
|
bool started = mThread.Start();
|
|
if (!started) {
|
|
NS_WARNING("Unable to start GMPThread!");
|
|
return;
|
|
}
|
|
}
|
|
|
|
nsRefPtr<Runnable> r = new Runnable(aTask);
|
|
|
|
mThread.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(r.get(), &Runnable::Run));
|
|
}
|
|
|
|
void
|
|
GMPThreadImpl::Join()
|
|
{
|
|
MutexAutoLock lock(mMutex);
|
|
if (mThread.IsRunning()) {
|
|
mThread.Stop();
|
|
}
|
|
}
|
|
|
|
GMPMutexImpl::GMPMutexImpl()
|
|
: mMutex("gmp-mutex")
|
|
{
|
|
}
|
|
|
|
GMPMutexImpl::~GMPMutexImpl()
|
|
{
|
|
}
|
|
|
|
void
|
|
GMPMutexImpl::Acquire()
|
|
{
|
|
mMutex.Lock();
|
|
}
|
|
|
|
void
|
|
GMPMutexImpl::Release()
|
|
{
|
|
mMutex.Unlock();
|
|
}
|
|
|
|
} // namespace gmp
|
|
} // namespace mozilla
|