1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/ipdl/test/cxx/TestInterruptRaces.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,231 @@ 1.4 +#include "TestInterruptRaces.h" 1.5 + 1.6 +#include "IPDLUnitTests.h" // fail etc. 1.7 + 1.8 +using mozilla::ipc::MessageChannel; 1.9 + 1.10 +template<> 1.11 +struct RunnableMethodTraits<mozilla::_ipdltest::TestInterruptRacesParent> 1.12 +{ 1.13 + static void RetainCallee(mozilla::_ipdltest::TestInterruptRacesParent* obj) { } 1.14 + static void ReleaseCallee(mozilla::_ipdltest::TestInterruptRacesParent* obj) { } 1.15 +}; 1.16 + 1.17 + 1.18 +namespace mozilla { 1.19 +namespace _ipdltest { 1.20 + 1.21 +ipc::RacyInterruptPolicy 1.22 +MediateRace(const MessageChannel::Message& parent, 1.23 + const MessageChannel::Message& child) 1.24 +{ 1.25 + return (PTestInterruptRaces::Msg_Child__ID == parent.type()) ? 1.26 + ipc::RIPParentWins : ipc::RIPChildWins; 1.27 +} 1.28 + 1.29 +//----------------------------------------------------------------------------- 1.30 +// parent 1.31 +void 1.32 +TestInterruptRacesParent::Main() 1.33 +{ 1.34 + if (!SendStart()) 1.35 + fail("sending Start()"); 1.36 +} 1.37 + 1.38 +bool 1.39 +TestInterruptRacesParent::RecvStartRace() 1.40 +{ 1.41 + MessageLoop::current()->PostTask( 1.42 + FROM_HERE, 1.43 + NewRunnableMethod(this, &TestInterruptRacesParent::OnRaceTime)); 1.44 + return true; 1.45 +} 1.46 + 1.47 +void 1.48 +TestInterruptRacesParent::OnRaceTime() 1.49 +{ 1.50 + if (!CallRace(&mChildHasReply)) 1.51 + fail("problem calling Race()"); 1.52 + 1.53 + if (!mChildHasReply) 1.54 + fail("child should have got a reply already"); 1.55 + 1.56 + mHasReply = true; 1.57 + 1.58 + MessageLoop::current()->PostTask( 1.59 + FROM_HERE, 1.60 + NewRunnableMethod(this, &TestInterruptRacesParent::Test2)); 1.61 +} 1.62 + 1.63 +bool 1.64 +TestInterruptRacesParent::AnswerRace(bool* hasReply) 1.65 +{ 1.66 + if (mHasReply) 1.67 + fail("apparently the parent won the Interrupt race!"); 1.68 + *hasReply = hasReply; 1.69 + return true; 1.70 +} 1.71 + 1.72 +void 1.73 +TestInterruptRacesParent::Test2() 1.74 +{ 1.75 + puts(" passed"); 1.76 + puts("Test 2"); 1.77 + 1.78 + mHasReply = false; 1.79 + mChildHasReply = false; 1.80 + 1.81 + if (!CallStackFrame()) 1.82 + fail("can't set up a stack frame"); 1.83 + 1.84 + puts(" passed"); 1.85 + 1.86 + MessageLoop::current()->PostTask( 1.87 + FROM_HERE, 1.88 + NewRunnableMethod(this, &TestInterruptRacesParent::Test3)); 1.89 +} 1.90 + 1.91 +bool 1.92 +TestInterruptRacesParent::AnswerStackFrame() 1.93 +{ 1.94 + if (!SendWakeup()) 1.95 + fail("can't wake up the child"); 1.96 + 1.97 + if (!CallRace(&mChildHasReply)) 1.98 + fail("can't set up race condition"); 1.99 + mHasReply = true; 1.100 + 1.101 + if (!mChildHasReply) 1.102 + fail("child should have got a reply already"); 1.103 + 1.104 + return true; 1.105 +} 1.106 + 1.107 +void 1.108 +TestInterruptRacesParent::Test3() 1.109 +{ 1.110 + puts("Test 3"); 1.111 + 1.112 + if (!CallStackFrame3()) 1.113 + fail("can't set up a stack frame"); 1.114 + 1.115 + puts(" passed"); 1.116 + 1.117 + Close(); 1.118 +} 1.119 + 1.120 +bool 1.121 +TestInterruptRacesParent::AnswerStackFrame3() 1.122 +{ 1.123 + if (!SendWakeup3()) 1.124 + fail("can't wake up the child"); 1.125 + 1.126 + if (!CallChild()) 1.127 + fail("can't set up race condition"); 1.128 + 1.129 + return true; 1.130 +} 1.131 + 1.132 +bool 1.133 +TestInterruptRacesParent::AnswerParent() 1.134 +{ 1.135 + mAnsweredParent = true; 1.136 + return true; 1.137 +} 1.138 + 1.139 +bool 1.140 +TestInterruptRacesParent::RecvGetAnsweredParent(bool* answeredParent) 1.141 +{ 1.142 + *answeredParent = mAnsweredParent; 1.143 + return true; 1.144 +} 1.145 + 1.146 +//----------------------------------------------------------------------------- 1.147 +// child 1.148 +bool 1.149 +TestInterruptRacesChild::RecvStart() 1.150 +{ 1.151 + puts("Test 1"); 1.152 + 1.153 + if (!SendStartRace()) 1.154 + fail("problem sending StartRace()"); 1.155 + 1.156 + bool dontcare; 1.157 + if (!CallRace(&dontcare)) 1.158 + fail("problem calling Race()"); 1.159 + 1.160 + mHasReply = true; 1.161 + return true; 1.162 +} 1.163 + 1.164 +bool 1.165 +TestInterruptRacesChild::AnswerRace(bool* hasReply) 1.166 +{ 1.167 + if (!mHasReply) 1.168 + fail("apparently the child lost the Interrupt race!"); 1.169 + 1.170 + *hasReply = mHasReply; 1.171 + 1.172 + return true; 1.173 +} 1.174 + 1.175 +bool 1.176 +TestInterruptRacesChild::AnswerStackFrame() 1.177 +{ 1.178 + // reset for the second test 1.179 + mHasReply = false; 1.180 + 1.181 + if (!CallStackFrame()) 1.182 + fail("can't set up stack frame"); 1.183 + 1.184 + if (!mHasReply) 1.185 + fail("should have had reply by now"); 1.186 + 1.187 + return true; 1.188 +} 1.189 + 1.190 +bool 1.191 +TestInterruptRacesChild::RecvWakeup() 1.192 +{ 1.193 + bool dontcare; 1.194 + if (!CallRace(&dontcare)) 1.195 + fail("can't set up race condition"); 1.196 + 1.197 + mHasReply = true; 1.198 + return true; 1.199 +} 1.200 + 1.201 +bool 1.202 +TestInterruptRacesChild::AnswerStackFrame3() 1.203 +{ 1.204 + if (!CallStackFrame3()) 1.205 + fail("can't set up stack frame"); 1.206 + return true; 1.207 +} 1.208 + 1.209 +bool 1.210 +TestInterruptRacesChild::RecvWakeup3() 1.211 +{ 1.212 + if (!CallParent()) 1.213 + fail("can't set up race condition"); 1.214 + return true; 1.215 +} 1.216 + 1.217 +bool 1.218 +TestInterruptRacesChild::AnswerChild() 1.219 +{ 1.220 + bool parentAnsweredParent; 1.221 + // the parent is supposed to win the race, which means its 1.222 + // message, Child(), is supposed to be processed before the 1.223 + // child's message, Parent() 1.224 + if (!SendGetAnsweredParent(&parentAnsweredParent)) 1.225 + fail("sending GetAnsweredParent"); 1.226 + 1.227 + if (parentAnsweredParent) 1.228 + fail("parent was supposed to win the race!"); 1.229 + 1.230 + return true; 1.231 +} 1.232 + 1.233 +} // namespace _ipdltest 1.234 +} // namespace mozilla