summaryrefslogtreecommitdiffstats
path: root/ipc/ipdl/test/cxx/TestActorPunning.cpp
blob: 5825796f5479ba637cc2f95a2975f6cd91e2b7fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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