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
|