gecko-dev/ipc/ipdl/test/cxx/TestActorPunning.cpp

153 строки
3.6 KiB
C++

#include "TestActorPunning.h"
#include "IPDLUnitTests.h" // fail etc.
#include "mozilla/Unused.h"
namespace mozilla {
namespace _ipdltest {
//-----------------------------------------------------------------------------
// parent
void
TestActorPunningParent::Main()
{
if (!SendStart())
fail("sending Start");
}
mozilla::ipc::IPCResult
TestActorPunningParent::RecvPun(PTestActorPunningSubParent* a, const Bad& bad)
{
if (a->SendBad())
fail("bad!");
fail("shouldn't have received this message in the first place");
return IPC_OK();
}
// By default, fatal errors kill the parent process, but this makes it
// hard to test, so instead we use the previous behavior and kill the
// child process.
void
TestActorPunningParent::HandleFatalError(const char* aProtocolName, const char* aErrorMsg) const
{
if (!!strcmp(aProtocolName, "PTestActorPunningParent")) {
fail("wrong protocol hit a fatal error");
}
if (!!strcmp(aErrorMsg, "Error deserializing 'PTestActorPunningSubParent'")) {
fail("wrong fatal error");
}
ipc::ScopedProcessHandle otherProcessHandle;
if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle.rwget())) {
fail("couldn't open child process");
} else {
if (!base::KillProcess(otherProcessHandle, 0, false)) {
fail("terminating child process");
}
}
}
PTestActorPunningPunnedParent*
TestActorPunningParent::AllocPTestActorPunningPunnedParent()
{
return new TestActorPunningPunnedParent();
}
bool
TestActorPunningParent::DeallocPTestActorPunningPunnedParent(PTestActorPunningPunnedParent* a)
{
delete a;
return true;
}
PTestActorPunningSubParent*
TestActorPunningParent::AllocPTestActorPunningSubParent()
{
return new TestActorPunningSubParent();
}
bool
TestActorPunningParent::DeallocPTestActorPunningSubParent(PTestActorPunningSubParent* a)
{
delete a;
return true;
}
//-----------------------------------------------------------------------------
// child
PTestActorPunningPunnedChild*
TestActorPunningChild::AllocPTestActorPunningPunnedChild()
{
return new TestActorPunningPunnedChild();
}
bool
TestActorPunningChild::DeallocPTestActorPunningPunnedChild(PTestActorPunningPunnedChild*)
{
fail("should have died by now");
return true;
}
PTestActorPunningSubChild*
TestActorPunningChild::AllocPTestActorPunningSubChild()
{
return new TestActorPunningSubChild();
}
bool
TestActorPunningChild::DeallocPTestActorPunningSubChild(PTestActorPunningSubChild*)
{
fail("should have died by now");
return true;
}
mozilla::ipc::IPCResult
TestActorPunningChild::RecvStart()
{
SendPTestActorPunningSubConstructor();
SendPTestActorPunningPunnedConstructor();
PTestActorPunningSubChild* a = SendPTestActorPunningSubConstructor();
// We can't assert whether this succeeds or fails, due to race
// conditions.
SendPun(a, Bad());
return IPC_OK();
}
mozilla::ipc::IPCResult
TestActorPunningSubChild::RecvBad()
{
fail("things are going really badly right now");
return IPC_OK();
}
} // namespace _ipdltest
} // namespace mozilla
namespace IPC {
using namespace mozilla::_ipdltest;
using namespace mozilla::ipc;
/*static*/ void
ParamTraits<Bad>::Write(Message* aMsg, const paramType& aParam)
{
// Skip past the sentinel for the actor as well as the actor.
int32_t* ptr = aMsg->GetInt32PtrForTest(2 * sizeof(int32_t));
ActorHandle* ah = reinterpret_cast<ActorHandle*>(ptr);
if (ah->mId != -3)
fail("guessed wrong offset (value is %d, should be -3)", ah->mId);
ah->mId = -2;
}
/*static*/ bool
ParamTraits<Bad>::Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return true;
}
} // namespace IPC