1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/ipdl/test/cxx/TestBridgeMain.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,252 @@ 1.4 +#include "TestBridgeMain.h" 1.5 + 1.6 +#include "IPDLUnitTests.h" // fail etc. 1.7 +#include "IPDLUnitTestSubprocess.h" 1.8 + 1.9 +using namespace std; 1.10 + 1.11 +template<> 1.12 +struct RunnableMethodTraits<mozilla::_ipdltest::TestBridgeMainSubChild> 1.13 +{ 1.14 + static void RetainCallee(mozilla::_ipdltest::TestBridgeMainSubChild* obj) { } 1.15 + static void ReleaseCallee(mozilla::_ipdltest::TestBridgeMainSubChild* obj) { } 1.16 +}; 1.17 + 1.18 +namespace mozilla { 1.19 +namespace _ipdltest { 1.20 + 1.21 + 1.22 +//----------------------------------------------------------------------------- 1.23 +// main process 1.24 +void 1.25 +TestBridgeMainParent::Main() 1.26 +{ 1.27 + if (!SendStart()) 1.28 + fail("sending Start"); 1.29 +} 1.30 + 1.31 +PTestBridgeMainSubParent* 1.32 +TestBridgeMainParent::AllocPTestBridgeMainSubParent(Transport* transport, 1.33 + ProcessId otherProcess) 1.34 +{ 1.35 + ProcessHandle h; 1.36 + if (!base::OpenProcessHandle(otherProcess, &h)) { 1.37 + return nullptr; 1.38 + } 1.39 + 1.40 + nsAutoPtr<TestBridgeMainSubParent> a(new TestBridgeMainSubParent(transport)); 1.41 + if (!a->Open(transport, h, XRE_GetIOMessageLoop(), ipc::ParentSide)) { 1.42 + return nullptr; 1.43 + } 1.44 + return a.forget(); 1.45 +} 1.46 + 1.47 +void 1.48 +TestBridgeMainParent::ActorDestroy(ActorDestroyReason why) 1.49 +{ 1.50 + if (NormalShutdown != why) 1.51 + fail("unexpected destruction!"); 1.52 + passed("ok"); 1.53 + QuitParent(); 1.54 +} 1.55 + 1.56 +bool 1.57 +TestBridgeMainSubParent::RecvHello() 1.58 +{ 1.59 + return SendHi(); 1.60 +} 1.61 + 1.62 +bool 1.63 +TestBridgeMainSubParent::RecvHelloSync() 1.64 +{ 1.65 + return true; 1.66 +} 1.67 + 1.68 +bool 1.69 +TestBridgeMainSubParent::AnswerHelloRpc() 1.70 +{ 1.71 + return CallHiRpc(); 1.72 +} 1.73 + 1.74 +void 1.75 +TestBridgeMainSubParent::ActorDestroy(ActorDestroyReason why) 1.76 +{ 1.77 + if (NormalShutdown != why) 1.78 + fail("unexpected destruction!"); 1.79 + 1.80 + // ActorDestroy() is just a callback from IPDL-generated code, 1.81 + // which needs the top-level actor (this) to stay alive a little 1.82 + // longer so other things can be cleaned up. 1.83 + MessageLoop::current()->PostTask( 1.84 + FROM_HERE, 1.85 + new DeleteTask<TestBridgeMainSubParent>(this)); 1.86 + XRE_GetIOMessageLoop()->PostTask( 1.87 + FROM_HERE, 1.88 + new DeleteTask<Transport>(mTransport)); 1.89 +} 1.90 + 1.91 +//----------------------------------------------------------------------------- 1.92 +// sub process --- child of main 1.93 +TestBridgeMainChild* gBridgeMainChild; 1.94 + 1.95 +TestBridgeMainChild::TestBridgeMainChild() 1.96 + : mSubprocess(nullptr) 1.97 +{ 1.98 + gBridgeMainChild = this; 1.99 +} 1.100 + 1.101 +bool 1.102 +TestBridgeMainChild::RecvStart() 1.103 +{ 1.104 + vector<string> subsubArgs; 1.105 + subsubArgs.push_back("TestBridgeSub"); 1.106 + 1.107 + mSubprocess = new IPDLUnitTestSubprocess(); 1.108 + if (!mSubprocess->SyncLaunch(subsubArgs)) 1.109 + fail("problem launching subprocess"); 1.110 + 1.111 + IPC::Channel* transport = mSubprocess->GetChannel(); 1.112 + if (!transport) 1.113 + fail("no transport"); 1.114 + 1.115 + TestBridgeSubParent* bsp = new TestBridgeSubParent(); 1.116 + bsp->Open(transport, mSubprocess->GetChildProcessHandle()); 1.117 + 1.118 + bsp->Main(); 1.119 + return true; 1.120 +} 1.121 + 1.122 +void 1.123 +TestBridgeMainChild::ActorDestroy(ActorDestroyReason why) 1.124 +{ 1.125 + if (NormalShutdown != why) 1.126 + fail("unexpected destruction!"); 1.127 + // NB: this is kosher because QuitChild() joins with the IO thread 1.128 + XRE_GetIOMessageLoop()->PostTask( 1.129 + FROM_HERE, 1.130 + new DeleteTask<IPDLUnitTestSubprocess>(mSubprocess)); 1.131 + QuitChild(); 1.132 +} 1.133 + 1.134 +void 1.135 +TestBridgeSubParent::Main() 1.136 +{ 1.137 + if (!SendPing()) 1.138 + fail("sending Ping"); 1.139 +} 1.140 + 1.141 +bool 1.142 +TestBridgeSubParent::RecvBridgeEm() 1.143 +{ 1.144 + if (!PTestBridgeMainSub::Bridge(gBridgeMainChild, this)) 1.145 + fail("bridging Main and Sub"); 1.146 + return true; 1.147 +} 1.148 + 1.149 +void 1.150 +TestBridgeSubParent::ActorDestroy(ActorDestroyReason why) 1.151 +{ 1.152 + if (NormalShutdown != why) 1.153 + fail("unexpected destruction!"); 1.154 + gBridgeMainChild->Close(); 1.155 + 1.156 + // ActorDestroy() is just a callback from IPDL-generated code, 1.157 + // which needs the top-level actor (this) to stay alive a little 1.158 + // longer so other things can be cleaned up. 1.159 + MessageLoop::current()->PostTask( 1.160 + FROM_HERE, 1.161 + new DeleteTask<TestBridgeSubParent>(this)); 1.162 +} 1.163 + 1.164 +//----------------------------------------------------------------------------- 1.165 +// subsub process --- child of sub 1.166 + 1.167 +static TestBridgeSubChild* gBridgeSubChild; 1.168 + 1.169 +TestBridgeSubChild::TestBridgeSubChild() 1.170 +{ 1.171 + gBridgeSubChild = this; 1.172 +} 1.173 + 1.174 +bool 1.175 +TestBridgeSubChild::RecvPing() 1.176 +{ 1.177 + if (!SendBridgeEm()) 1.178 + fail("sending BridgeEm"); 1.179 + return true; 1.180 +} 1.181 + 1.182 +PTestBridgeMainSubChild* 1.183 +TestBridgeSubChild::AllocPTestBridgeMainSubChild(Transport* transport, 1.184 + ProcessId otherProcess) 1.185 +{ 1.186 + ProcessHandle h; 1.187 + if (!base::OpenProcessHandle(otherProcess, &h)) { 1.188 + return nullptr; 1.189 + } 1.190 + 1.191 + nsAutoPtr<TestBridgeMainSubChild> a(new TestBridgeMainSubChild(transport)); 1.192 + if (!a->Open(transport, h, XRE_GetIOMessageLoop(), ipc::ChildSide)) { 1.193 + return nullptr; 1.194 + } 1.195 + 1.196 + if (!a->SendHello()) 1.197 + fail("sending Hello"); 1.198 + 1.199 + return a.forget(); 1.200 +} 1.201 + 1.202 +void 1.203 +TestBridgeSubChild::ActorDestroy(ActorDestroyReason why) 1.204 +{ 1.205 + if (NormalShutdown != why) 1.206 + fail("unexpected destruction!"); 1.207 + QuitChild(); 1.208 +} 1.209 + 1.210 +bool 1.211 +TestBridgeMainSubChild::RecvHi() 1.212 +{ 1.213 + if (!SendHelloSync()) 1.214 + fail("sending HelloSync"); 1.215 + if (!CallHelloRpc()) 1.216 + fail("calling HelloRpc"); 1.217 + if (!mGotHi) 1.218 + fail("didn't answer HiRpc"); 1.219 + 1.220 + // Need to close the channel without message-processing frames on 1.221 + // the C++ stack 1.222 + MessageLoop::current()->PostTask( 1.223 + FROM_HERE, 1.224 + NewRunnableMethod(this, &TestBridgeMainSubChild::Close)); 1.225 + return true; 1.226 +} 1.227 + 1.228 +bool 1.229 +TestBridgeMainSubChild::AnswerHiRpc() 1.230 +{ 1.231 + mGotHi = true; // d00d 1.232 + return true; 1.233 +} 1.234 + 1.235 +void 1.236 +TestBridgeMainSubChild::ActorDestroy(ActorDestroyReason why) 1.237 +{ 1.238 + if (NormalShutdown != why) 1.239 + fail("unexpected destruction!"); 1.240 + 1.241 + gBridgeSubChild->Close(); 1.242 + 1.243 + // ActorDestroy() is just a callback from IPDL-generated code, 1.244 + // which needs the top-level actor (this) to stay alive a little 1.245 + // longer so other things can be cleaned up. 1.246 + MessageLoop::current()->PostTask( 1.247 + FROM_HERE, 1.248 + new DeleteTask<TestBridgeMainSubChild>(this)); 1.249 + XRE_GetIOMessageLoop()->PostTask( 1.250 + FROM_HERE, 1.251 + new DeleteTask<Transport>(mTransport)); 1.252 +} 1.253 + 1.254 +} // namespace mozilla 1.255 +} // namespace _ipdltest