#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* aErrorMsg) { 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::Write(MessageWriter* aWriter, const paramType& aParam) { // Skip past the sentinel for the actor as well as the actor. int32_t* ptr = aWriter->GetInt32PtrForTest(2 * sizeof(int32_t)); ActorHandle* ah = reinterpret_cast(ptr); if (ah->mId != -3) fail("guessed wrong offset (value is %d, should be -3)", ah->mId); ah->mId = -2; } /*static*/ bool ParamTraits::Read(MessageReader* aReader, paramType* aResult) { return true; } } // namespace IPC