michael@0: #include "TestInterruptRaces.h" michael@0: michael@0: #include "IPDLUnitTests.h" // fail etc. michael@0: michael@0: using mozilla::ipc::MessageChannel; michael@0: michael@0: template<> michael@0: struct RunnableMethodTraits michael@0: { michael@0: static void RetainCallee(mozilla::_ipdltest::TestInterruptRacesParent* obj) { } michael@0: static void ReleaseCallee(mozilla::_ipdltest::TestInterruptRacesParent* obj) { } michael@0: }; michael@0: michael@0: michael@0: namespace mozilla { michael@0: namespace _ipdltest { michael@0: michael@0: ipc::RacyInterruptPolicy michael@0: MediateRace(const MessageChannel::Message& parent, michael@0: const MessageChannel::Message& child) michael@0: { michael@0: return (PTestInterruptRaces::Msg_Child__ID == parent.type()) ? michael@0: ipc::RIPParentWins : ipc::RIPChildWins; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // parent michael@0: void michael@0: TestInterruptRacesParent::Main() michael@0: { michael@0: if (!SendStart()) michael@0: fail("sending Start()"); michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesParent::RecvStartRace() michael@0: { michael@0: MessageLoop::current()->PostTask( michael@0: FROM_HERE, michael@0: NewRunnableMethod(this, &TestInterruptRacesParent::OnRaceTime)); michael@0: return true; michael@0: } michael@0: michael@0: void michael@0: TestInterruptRacesParent::OnRaceTime() michael@0: { michael@0: if (!CallRace(&mChildHasReply)) michael@0: fail("problem calling Race()"); michael@0: michael@0: if (!mChildHasReply) michael@0: fail("child should have got a reply already"); michael@0: michael@0: mHasReply = true; michael@0: michael@0: MessageLoop::current()->PostTask( michael@0: FROM_HERE, michael@0: NewRunnableMethod(this, &TestInterruptRacesParent::Test2)); michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesParent::AnswerRace(bool* hasReply) michael@0: { michael@0: if (mHasReply) michael@0: fail("apparently the parent won the Interrupt race!"); michael@0: *hasReply = hasReply; michael@0: return true; michael@0: } michael@0: michael@0: void michael@0: TestInterruptRacesParent::Test2() michael@0: { michael@0: puts(" passed"); michael@0: puts("Test 2"); michael@0: michael@0: mHasReply = false; michael@0: mChildHasReply = false; michael@0: michael@0: if (!CallStackFrame()) michael@0: fail("can't set up a stack frame"); michael@0: michael@0: puts(" passed"); michael@0: michael@0: MessageLoop::current()->PostTask( michael@0: FROM_HERE, michael@0: NewRunnableMethod(this, &TestInterruptRacesParent::Test3)); michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesParent::AnswerStackFrame() michael@0: { michael@0: if (!SendWakeup()) michael@0: fail("can't wake up the child"); michael@0: michael@0: if (!CallRace(&mChildHasReply)) michael@0: fail("can't set up race condition"); michael@0: mHasReply = true; michael@0: michael@0: if (!mChildHasReply) michael@0: fail("child should have got a reply already"); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: void michael@0: TestInterruptRacesParent::Test3() michael@0: { michael@0: puts("Test 3"); michael@0: michael@0: if (!CallStackFrame3()) michael@0: fail("can't set up a stack frame"); michael@0: michael@0: puts(" passed"); michael@0: michael@0: Close(); michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesParent::AnswerStackFrame3() michael@0: { michael@0: if (!SendWakeup3()) michael@0: fail("can't wake up the child"); michael@0: michael@0: if (!CallChild()) michael@0: fail("can't set up race condition"); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesParent::AnswerParent() michael@0: { michael@0: mAnsweredParent = true; michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesParent::RecvGetAnsweredParent(bool* answeredParent) michael@0: { michael@0: *answeredParent = mAnsweredParent; michael@0: return true; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // child michael@0: bool michael@0: TestInterruptRacesChild::RecvStart() michael@0: { michael@0: puts("Test 1"); michael@0: michael@0: if (!SendStartRace()) michael@0: fail("problem sending StartRace()"); michael@0: michael@0: bool dontcare; michael@0: if (!CallRace(&dontcare)) michael@0: fail("problem calling Race()"); michael@0: michael@0: mHasReply = true; michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesChild::AnswerRace(bool* hasReply) michael@0: { michael@0: if (!mHasReply) michael@0: fail("apparently the child lost the Interrupt race!"); michael@0: michael@0: *hasReply = mHasReply; michael@0: michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesChild::AnswerStackFrame() michael@0: { michael@0: // reset for the second test michael@0: mHasReply = false; michael@0: michael@0: if (!CallStackFrame()) michael@0: fail("can't set up stack frame"); michael@0: michael@0: if (!mHasReply) michael@0: fail("should have had reply by now"); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesChild::RecvWakeup() michael@0: { michael@0: bool dontcare; michael@0: if (!CallRace(&dontcare)) michael@0: fail("can't set up race condition"); michael@0: michael@0: mHasReply = true; michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesChild::AnswerStackFrame3() michael@0: { michael@0: if (!CallStackFrame3()) michael@0: fail("can't set up stack frame"); michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesChild::RecvWakeup3() michael@0: { michael@0: if (!CallParent()) michael@0: fail("can't set up race condition"); michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: TestInterruptRacesChild::AnswerChild() michael@0: { michael@0: bool parentAnsweredParent; michael@0: // the parent is supposed to win the race, which means its michael@0: // message, Child(), is supposed to be processed before the michael@0: // child's message, Parent() michael@0: if (!SendGetAnsweredParent(&parentAnsweredParent)) michael@0: fail("sending GetAnsweredParent"); michael@0: michael@0: if (parentAnsweredParent) michael@0: fail("parent was supposed to win the race!"); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: } // namespace _ipdltest michael@0: } // namespace mozilla