diff options
Diffstat (limited to 'ipc/ipdl/test/cxx/TestActorPunning.cpp')
-rw-r--r-- | ipc/ipdl/test/cxx/TestActorPunning.cpp | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/ipc/ipdl/test/cxx/TestActorPunning.cpp b/ipc/ipdl/test/cxx/TestActorPunning.cpp new file mode 100644 index 0000000000..5825796f54 --- /dev/null +++ b/ipc/ipdl/test/cxx/TestActorPunning.cpp @@ -0,0 +1,125 @@ +#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<Bad>::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<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(MessageReader* aReader, + paramType* aResult) { + return true; +} + +} // namespace IPC |