зеркало из https://github.com/mozilla/gecko-dev.git
153 строки
4.3 KiB
C++
153 строки
4.3 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: sw=4 ts=4 et :
|
|
* 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 "FunctionBrokerParent.h"
|
|
#include "FunctionBroker.h"
|
|
#include "FunctionBrokerThread.h"
|
|
|
|
namespace mozilla {
|
|
namespace plugins {
|
|
|
|
#if defined(XP_WIN)
|
|
UlongPairToIdMap sPairToIdMap;
|
|
IdToUlongPairMap sIdToPairMap;
|
|
PtrToIdMap sPtrToIdMap;
|
|
IdToPtrMap sIdToPtrMap;
|
|
#endif // defined(XP_WIN)
|
|
|
|
/* static */ FunctionBrokerParent*
|
|
FunctionBrokerParent::Create(Endpoint<PFunctionBrokerParent>&& aParentEnd)
|
|
{
|
|
FunctionBrokerThread* thread = FunctionBrokerThread::Create();
|
|
if (!thread) {
|
|
return nullptr;
|
|
}
|
|
|
|
// We get the FunctionHooks so that they are created here, not on the
|
|
// message thread.
|
|
FunctionHook::GetHooks();
|
|
|
|
return new FunctionBrokerParent(thread, std::move(aParentEnd));
|
|
}
|
|
|
|
FunctionBrokerParent::FunctionBrokerParent(FunctionBrokerThread* aThread,
|
|
Endpoint<PFunctionBrokerParent>&& aParentEnd) :
|
|
mThread(aThread)
|
|
, mMonitor("FunctionBrokerParent Lock")
|
|
, mShutdownDone(false)
|
|
{
|
|
MOZ_ASSERT(mThread);
|
|
mThread->Dispatch(NewNonOwningRunnableMethod<Endpoint<PFunctionBrokerParent>&&>(
|
|
"FunctionBrokerParent::Bind", this, &FunctionBrokerParent::Bind, std::move(aParentEnd)));
|
|
}
|
|
|
|
FunctionBrokerParent::~FunctionBrokerParent()
|
|
{
|
|
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
|
// Clean up any file permissions that we granted to the child process.
|
|
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
|
RemovePermissionsForProcess(OtherPid());
|
|
#endif
|
|
}
|
|
|
|
void
|
|
FunctionBrokerParent::Bind(Endpoint<PFunctionBrokerParent>&& aEnd)
|
|
{
|
|
MOZ_RELEASE_ASSERT(mThread->IsOnThread());
|
|
DebugOnly<bool> ok = aEnd.Bind(this);
|
|
MOZ_ASSERT(ok);
|
|
}
|
|
|
|
void
|
|
FunctionBrokerParent::ShutdownOnBrokerThread()
|
|
{
|
|
MOZ_ASSERT(mThread->IsOnThread());
|
|
Close();
|
|
|
|
// Notify waiting thread that we are done.
|
|
MonitorAutoLock lock(mMonitor);
|
|
mShutdownDone = true;
|
|
mMonitor.Notify();
|
|
}
|
|
|
|
void
|
|
FunctionBrokerParent::Destroy(FunctionBrokerParent* aInst)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(aInst);
|
|
|
|
{
|
|
// Hold the lock while we destroy the actor on the broker thread.
|
|
MonitorAutoLock lock(aInst->mMonitor);
|
|
aInst->mThread->Dispatch(NewNonOwningRunnableMethod(
|
|
"FunctionBrokerParent::ShutdownOnBrokerThread", aInst,
|
|
&FunctionBrokerParent::ShutdownOnBrokerThread));
|
|
|
|
// Wait for broker thread to complete destruction.
|
|
while (!aInst->mShutdownDone) {
|
|
aInst->mMonitor.Wait();
|
|
}
|
|
}
|
|
|
|
delete aInst;
|
|
}
|
|
|
|
void
|
|
FunctionBrokerParent::ActorDestroy(ActorDestroyReason aWhy)
|
|
{
|
|
MOZ_RELEASE_ASSERT(mThread->IsOnThread());
|
|
}
|
|
|
|
mozilla::ipc::IPCResult
|
|
FunctionBrokerParent::RecvBrokerFunction(const FunctionHookId &aFunctionId,
|
|
const IpdlTuple &aInTuple,
|
|
IpdlTuple *aOutTuple)
|
|
{
|
|
#if defined(XP_WIN)
|
|
MOZ_ASSERT(mThread->IsOnThread());
|
|
if (RunBrokeredFunction(OtherPid(), aFunctionId, aInTuple, aOutTuple)) {
|
|
return IPC_OK();
|
|
}
|
|
return IPC_FAIL_NO_REASON(this);
|
|
#else
|
|
MOZ_ASSERT_UNREACHABLE("BrokerFunction is currently only implemented on Windows.");
|
|
return IPC_FAIL_NO_REASON(this);
|
|
#endif
|
|
}
|
|
|
|
// static
|
|
bool
|
|
FunctionBrokerParent::RunBrokeredFunction(base::ProcessId aClientId,
|
|
const FunctionHookId &aFunctionId,
|
|
const IPC::IpdlTuple &aInTuple,
|
|
IPC::IpdlTuple *aOutTuple)
|
|
{
|
|
if ((size_t)aFunctionId >= FunctionHook::GetHooks()->Length()) {
|
|
MOZ_ASSERT_UNREACHABLE("Invalid function ID");
|
|
return false;
|
|
}
|
|
|
|
FunctionHook* hook = FunctionHook::GetHooks()->ElementAt(aFunctionId);
|
|
MOZ_ASSERT(hook->FunctionId() == aFunctionId);
|
|
return hook->RunOriginalFunction(aClientId, aInTuple, aOutTuple);
|
|
}
|
|
|
|
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
|
|
|
mozilla::SandboxPermissions FunctionBrokerParent::sSandboxPermissions;
|
|
|
|
// static
|
|
void
|
|
FunctionBrokerParent::RemovePermissionsForProcess(base::ProcessId aClientId)
|
|
{
|
|
sSandboxPermissions.RemovePermissionsForProcess(aClientId);
|
|
}
|
|
|
|
#endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
|
|
|
|
} // namespace plugins
|
|
} // namespace mozilla
|