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