summaryrefslogtreecommitdiffstats
path: root/ipc/ipdl/test/cxx/TestActorPunning.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/ipdl/test/cxx/TestActorPunning.cpp')
-rw-r--r--ipc/ipdl/test/cxx/TestActorPunning.cpp125
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