Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 #include "TestBridgeMain.h"
3 #include "IPDLUnitTests.h" // fail etc.
4 #include "IPDLUnitTestSubprocess.h"
6 using namespace std;
8 template<>
9 struct RunnableMethodTraits<mozilla::_ipdltest::TestBridgeMainSubChild>
10 {
11 static void RetainCallee(mozilla::_ipdltest::TestBridgeMainSubChild* obj) { }
12 static void ReleaseCallee(mozilla::_ipdltest::TestBridgeMainSubChild* obj) { }
13 };
15 namespace mozilla {
16 namespace _ipdltest {
19 //-----------------------------------------------------------------------------
20 // main process
21 void
22 TestBridgeMainParent::Main()
23 {
24 if (!SendStart())
25 fail("sending Start");
26 }
28 PTestBridgeMainSubParent*
29 TestBridgeMainParent::AllocPTestBridgeMainSubParent(Transport* transport,
30 ProcessId otherProcess)
31 {
32 ProcessHandle h;
33 if (!base::OpenProcessHandle(otherProcess, &h)) {
34 return nullptr;
35 }
37 nsAutoPtr<TestBridgeMainSubParent> a(new TestBridgeMainSubParent(transport));
38 if (!a->Open(transport, h, XRE_GetIOMessageLoop(), ipc::ParentSide)) {
39 return nullptr;
40 }
41 return a.forget();
42 }
44 void
45 TestBridgeMainParent::ActorDestroy(ActorDestroyReason why)
46 {
47 if (NormalShutdown != why)
48 fail("unexpected destruction!");
49 passed("ok");
50 QuitParent();
51 }
53 bool
54 TestBridgeMainSubParent::RecvHello()
55 {
56 return SendHi();
57 }
59 bool
60 TestBridgeMainSubParent::RecvHelloSync()
61 {
62 return true;
63 }
65 bool
66 TestBridgeMainSubParent::AnswerHelloRpc()
67 {
68 return CallHiRpc();
69 }
71 void
72 TestBridgeMainSubParent::ActorDestroy(ActorDestroyReason why)
73 {
74 if (NormalShutdown != why)
75 fail("unexpected destruction!");
77 // ActorDestroy() is just a callback from IPDL-generated code,
78 // which needs the top-level actor (this) to stay alive a little
79 // longer so other things can be cleaned up.
80 MessageLoop::current()->PostTask(
81 FROM_HERE,
82 new DeleteTask<TestBridgeMainSubParent>(this));
83 XRE_GetIOMessageLoop()->PostTask(
84 FROM_HERE,
85 new DeleteTask<Transport>(mTransport));
86 }
88 //-----------------------------------------------------------------------------
89 // sub process --- child of main
90 TestBridgeMainChild* gBridgeMainChild;
92 TestBridgeMainChild::TestBridgeMainChild()
93 : mSubprocess(nullptr)
94 {
95 gBridgeMainChild = this;
96 }
98 bool
99 TestBridgeMainChild::RecvStart()
100 {
101 vector<string> subsubArgs;
102 subsubArgs.push_back("TestBridgeSub");
104 mSubprocess = new IPDLUnitTestSubprocess();
105 if (!mSubprocess->SyncLaunch(subsubArgs))
106 fail("problem launching subprocess");
108 IPC::Channel* transport = mSubprocess->GetChannel();
109 if (!transport)
110 fail("no transport");
112 TestBridgeSubParent* bsp = new TestBridgeSubParent();
113 bsp->Open(transport, mSubprocess->GetChildProcessHandle());
115 bsp->Main();
116 return true;
117 }
119 void
120 TestBridgeMainChild::ActorDestroy(ActorDestroyReason why)
121 {
122 if (NormalShutdown != why)
123 fail("unexpected destruction!");
124 // NB: this is kosher because QuitChild() joins with the IO thread
125 XRE_GetIOMessageLoop()->PostTask(
126 FROM_HERE,
127 new DeleteTask<IPDLUnitTestSubprocess>(mSubprocess));
128 QuitChild();
129 }
131 void
132 TestBridgeSubParent::Main()
133 {
134 if (!SendPing())
135 fail("sending Ping");
136 }
138 bool
139 TestBridgeSubParent::RecvBridgeEm()
140 {
141 if (!PTestBridgeMainSub::Bridge(gBridgeMainChild, this))
142 fail("bridging Main and Sub");
143 return true;
144 }
146 void
147 TestBridgeSubParent::ActorDestroy(ActorDestroyReason why)
148 {
149 if (NormalShutdown != why)
150 fail("unexpected destruction!");
151 gBridgeMainChild->Close();
153 // ActorDestroy() is just a callback from IPDL-generated code,
154 // which needs the top-level actor (this) to stay alive a little
155 // longer so other things can be cleaned up.
156 MessageLoop::current()->PostTask(
157 FROM_HERE,
158 new DeleteTask<TestBridgeSubParent>(this));
159 }
161 //-----------------------------------------------------------------------------
162 // subsub process --- child of sub
164 static TestBridgeSubChild* gBridgeSubChild;
166 TestBridgeSubChild::TestBridgeSubChild()
167 {
168 gBridgeSubChild = this;
169 }
171 bool
172 TestBridgeSubChild::RecvPing()
173 {
174 if (!SendBridgeEm())
175 fail("sending BridgeEm");
176 return true;
177 }
179 PTestBridgeMainSubChild*
180 TestBridgeSubChild::AllocPTestBridgeMainSubChild(Transport* transport,
181 ProcessId otherProcess)
182 {
183 ProcessHandle h;
184 if (!base::OpenProcessHandle(otherProcess, &h)) {
185 return nullptr;
186 }
188 nsAutoPtr<TestBridgeMainSubChild> a(new TestBridgeMainSubChild(transport));
189 if (!a->Open(transport, h, XRE_GetIOMessageLoop(), ipc::ChildSide)) {
190 return nullptr;
191 }
193 if (!a->SendHello())
194 fail("sending Hello");
196 return a.forget();
197 }
199 void
200 TestBridgeSubChild::ActorDestroy(ActorDestroyReason why)
201 {
202 if (NormalShutdown != why)
203 fail("unexpected destruction!");
204 QuitChild();
205 }
207 bool
208 TestBridgeMainSubChild::RecvHi()
209 {
210 if (!SendHelloSync())
211 fail("sending HelloSync");
212 if (!CallHelloRpc())
213 fail("calling HelloRpc");
214 if (!mGotHi)
215 fail("didn't answer HiRpc");
217 // Need to close the channel without message-processing frames on
218 // the C++ stack
219 MessageLoop::current()->PostTask(
220 FROM_HERE,
221 NewRunnableMethod(this, &TestBridgeMainSubChild::Close));
222 return true;
223 }
225 bool
226 TestBridgeMainSubChild::AnswerHiRpc()
227 {
228 mGotHi = true; // d00d
229 return true;
230 }
232 void
233 TestBridgeMainSubChild::ActorDestroy(ActorDestroyReason why)
234 {
235 if (NormalShutdown != why)
236 fail("unexpected destruction!");
238 gBridgeSubChild->Close();
240 // ActorDestroy() is just a callback from IPDL-generated code,
241 // which needs the top-level actor (this) to stay alive a little
242 // longer so other things can be cleaned up.
243 MessageLoop::current()->PostTask(
244 FROM_HERE,
245 new DeleteTask<TestBridgeMainSubChild>(this));
246 XRE_GetIOMessageLoop()->PostTask(
247 FROM_HERE,
248 new DeleteTask<Transport>(mTransport));
249 }
251 } // namespace mozilla
252 } // namespace _ipdltest