gecko-dev/ipc/ipdl/test/cxx/TestInterruptRaces.cpp

232 строки
4.5 KiB
C++

#include "TestInterruptRaces.h"
#include "IPDLUnitTests.h" // fail etc.
using mozilla::ipc::MessageChannel;
template<>
struct RunnableMethodTraits<mozilla::_ipdltest::TestInterruptRacesParent>
{
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