mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
7189c91e41
Backed out changeset a54b05c9e4a1 (bug 1028383) Backed out changeset 37985f79e0c2 (bug 774388) Backed out changeset d07521729077 (bug 774388) Backed out changeset 9f14b17f358c (bug 774388) Backed out changeset 2d347d6aa9bc (bug 774388) Backed out changeset 99581dfb5ec4 (bug 774388) Backed out changeset 2532e22d6135 (bug 774388) Backed out changeset 719844108f1a (bug 774388) Backed out changeset 7829c78348a4 (bug 1033358) Backed out changeset c571df9a85de (bug 1033358)
204 lines
6.3 KiB
C++
204 lines
6.3 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
* vim: sw=2 ts=8 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 "base/process_util.h"
|
|
|
|
#include "mozilla/ipc/MessageChannel.h"
|
|
#include "mozilla/ipc/ProtocolUtils.h"
|
|
#include "mozilla/ipc/Transport.h"
|
|
|
|
using namespace base;
|
|
using namespace IPC;
|
|
|
|
namespace mozilla {
|
|
namespace ipc {
|
|
|
|
IToplevelProtocol::~IToplevelProtocol()
|
|
{
|
|
mOpenActors.clear();
|
|
}
|
|
|
|
void IToplevelProtocol::AddOpenedActor(IToplevelProtocol* aActor)
|
|
{
|
|
#ifdef DEBUG
|
|
for (const IToplevelProtocol* actor = mOpenActors.getFirst();
|
|
actor;
|
|
actor = actor->getNext()) {
|
|
NS_ASSERTION(actor != aActor,
|
|
"Open the same protocol for more than one time");
|
|
}
|
|
#endif
|
|
|
|
mOpenActors.insertBack(aActor);
|
|
}
|
|
|
|
IToplevelProtocol*
|
|
IToplevelProtocol::CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
|
|
base::ProcessHandle aPeerProcess,
|
|
ProtocolCloneContext* aCtx)
|
|
{
|
|
NS_NOTREACHED("Clone() for this protocol actor is not implemented");
|
|
return nullptr;
|
|
}
|
|
|
|
void
|
|
IToplevelProtocol::CloneOpenedToplevels(IToplevelProtocol* aTemplate,
|
|
const InfallibleTArray<ProtocolFdMapping>& aFds,
|
|
base::ProcessHandle aPeerProcess,
|
|
ProtocolCloneContext* aCtx)
|
|
{
|
|
for (IToplevelProtocol* actor = aTemplate->GetFirstOpenedActors();
|
|
actor;
|
|
actor = actor->getNext()) {
|
|
IToplevelProtocol* newactor = actor->CloneToplevel(aFds, aPeerProcess, aCtx);
|
|
AddOpenedActor(newactor);
|
|
}
|
|
}
|
|
|
|
class ChannelOpened : public IPC::Message
|
|
{
|
|
public:
|
|
ChannelOpened(TransportDescriptor aDescriptor,
|
|
ProcessId aOtherProcess,
|
|
ProtocolId aProtocol)
|
|
: IPC::Message(MSG_ROUTING_CONTROL, // these only go to top-level actors
|
|
CHANNEL_OPENED_MESSAGE_TYPE,
|
|
PRIORITY_NORMAL)
|
|
{
|
|
IPC::WriteParam(this, aDescriptor);
|
|
IPC::WriteParam(this, aOtherProcess);
|
|
IPC::WriteParam(this, static_cast<uint32_t>(aProtocol));
|
|
}
|
|
|
|
static bool Read(const IPC::Message& aMsg,
|
|
TransportDescriptor* aDescriptor,
|
|
ProcessId* aOtherProcess,
|
|
ProtocolId* aProtocol)
|
|
{
|
|
void* iter = nullptr;
|
|
if (!IPC::ReadParam(&aMsg, &iter, aDescriptor) ||
|
|
!IPC::ReadParam(&aMsg, &iter, aOtherProcess) ||
|
|
!IPC::ReadParam(&aMsg, &iter, reinterpret_cast<uint32_t*>(aProtocol))) {
|
|
return false;
|
|
}
|
|
aMsg.EndRead(iter);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
bool
|
|
Bridge(const PrivateIPDLInterface&,
|
|
MessageChannel* aParentChannel, ProcessHandle aParentProcess,
|
|
MessageChannel* aChildChannel, ProcessHandle aChildProcess,
|
|
ProtocolId aProtocol, ProtocolId aChildProtocol)
|
|
{
|
|
ProcessId parentId = GetProcId(aParentProcess);
|
|
ProcessId childId = GetProcId(aChildProcess);
|
|
if (!parentId || !childId) {
|
|
return false;
|
|
}
|
|
|
|
TransportDescriptor parentSide, childSide;
|
|
if (!CreateTransport(aParentProcess, aChildProcess,
|
|
&parentSide, &childSide)) {
|
|
return false;
|
|
}
|
|
|
|
if (!aParentChannel->Send(new ChannelOpened(parentSide,
|
|
childId,
|
|
aProtocol)) ||
|
|
!aChildChannel->Send(new ChannelOpened(childSide,
|
|
parentId,
|
|
aChildProtocol))) {
|
|
CloseDescriptor(parentSide);
|
|
CloseDescriptor(childSide);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
Open(const PrivateIPDLInterface&,
|
|
MessageChannel* aOpenerChannel, ProcessHandle aOtherProcess,
|
|
Transport::Mode aOpenerMode,
|
|
ProtocolId aProtocol, ProtocolId aChildProtocol)
|
|
{
|
|
bool isParent = (Transport::MODE_SERVER == aOpenerMode);
|
|
ProcessHandle thisHandle = GetCurrentProcessHandle();
|
|
ProcessHandle parentHandle = isParent ? thisHandle : aOtherProcess;
|
|
ProcessHandle childHandle = !isParent ? thisHandle : aOtherProcess;
|
|
ProcessId parentId = GetProcId(parentHandle);
|
|
ProcessId childId = GetProcId(childHandle);
|
|
if (!parentId || !childId) {
|
|
return false;
|
|
}
|
|
|
|
TransportDescriptor parentSide, childSide;
|
|
if (!CreateTransport(parentHandle, childHandle,
|
|
&parentSide, &childSide)) {
|
|
return false;
|
|
}
|
|
|
|
Message* parentMsg = new ChannelOpened(parentSide, childId, aProtocol);
|
|
Message* childMsg = new ChannelOpened(childSide, parentId, aChildProtocol);
|
|
nsAutoPtr<Message> messageForUs(isParent ? parentMsg : childMsg);
|
|
nsAutoPtr<Message> messageForOtherSide(!isParent ? parentMsg : childMsg);
|
|
if (!aOpenerChannel->Echo(messageForUs.forget()) ||
|
|
!aOpenerChannel->Send(messageForOtherSide.forget())) {
|
|
CloseDescriptor(parentSide);
|
|
CloseDescriptor(childSide);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
UnpackChannelOpened(const PrivateIPDLInterface&,
|
|
const Message& aMsg,
|
|
TransportDescriptor* aTransport,
|
|
ProcessId* aOtherProcess,
|
|
ProtocolId* aProtocol)
|
|
{
|
|
return ChannelOpened::Read(aMsg, aTransport, aOtherProcess, aProtocol);
|
|
}
|
|
|
|
void
|
|
ProtocolErrorBreakpoint(const char* aMsg)
|
|
{
|
|
// Bugs that generate these error messages can be tough to
|
|
// reproduce. Log always in the hope that someone finds the error
|
|
// message.
|
|
printf_stderr("IPDL protocol error: %s\n", aMsg);
|
|
}
|
|
|
|
void
|
|
FatalError(const char* aProtocolName, const char* aMsg,
|
|
ProcessHandle aHandle, bool aIsParent)
|
|
{
|
|
ProtocolErrorBreakpoint(aMsg);
|
|
|
|
nsAutoCString formattedMessage("IPDL error [");
|
|
formattedMessage.AppendASCII(aProtocolName);
|
|
formattedMessage.AppendLiteral("]: \"");
|
|
formattedMessage.AppendASCII(aMsg);
|
|
if (aIsParent) {
|
|
formattedMessage.AppendLiteral("\". Killing child side as a result.");
|
|
NS_ERROR(formattedMessage.get());
|
|
|
|
if (aHandle != kInvalidProcessHandle &&
|
|
!base::KillProcess(aHandle, base::PROCESS_END_KILLED_BY_USER, false)) {
|
|
NS_ERROR("May have failed to kill child!");
|
|
}
|
|
} else {
|
|
formattedMessage.AppendLiteral("\". abort()ing as a result.");
|
|
NS_RUNTIMEABORT(formattedMessage.get());
|
|
}
|
|
}
|
|
|
|
} // namespace ipc
|
|
} // namespace mozilla
|