зеркало из https://github.com/mozilla/gecko-dev.git
Bug 561817 part A: Entered/ExitedCall callbacks for toplevel actors upon RPC in-calls. r=bsmedberg
This commit is contained in:
Родитель
c1e8abd08d
Коммит
01cd6e47af
|
@ -94,6 +94,16 @@ public:
|
|||
NS_RUNTIMEABORT("default impl shouldn't be invoked");
|
||||
}
|
||||
|
||||
virtual void OnEnteredCall()
|
||||
{
|
||||
NS_RUNTIMEABORT("default impl shouldn't be invoked");
|
||||
}
|
||||
|
||||
virtual void OnExitedCall()
|
||||
{
|
||||
NS_RUNTIMEABORT("default impl shouldn't be invoked");
|
||||
}
|
||||
|
||||
virtual RacyRPCPolicy MediateRPCRace(const Message& parent,
|
||||
const Message& child)
|
||||
{
|
||||
|
@ -199,12 +209,32 @@ protected:
|
|||
|
||||
void ExitedCxxStack();
|
||||
|
||||
void EnteredCall()
|
||||
{
|
||||
Listener()->OnEnteredCall();
|
||||
}
|
||||
|
||||
void ExitedCall()
|
||||
{
|
||||
Listener()->OnExitedCall();
|
||||
}
|
||||
|
||||
enum Direction { IN_MESSAGE, OUT_MESSAGE };
|
||||
struct RPCFrame {
|
||||
RPCFrame(Direction direction, const Message* msg) :
|
||||
mDirection(direction), mMsg(msg)
|
||||
{ }
|
||||
|
||||
bool IsRPCIncall() const
|
||||
{
|
||||
return mMsg->is_rpc() && IN_MESSAGE == mDirection;
|
||||
}
|
||||
|
||||
bool IsRPCOutcall() const
|
||||
{
|
||||
return mMsg->is_rpc() && OUT_MESSAGE == mDirection;
|
||||
}
|
||||
|
||||
void Describe(int32* id, const char** dir, const char** sems,
|
||||
const char** name) const
|
||||
{
|
||||
|
@ -230,11 +260,16 @@ protected:
|
|||
mThat.EnteredCxxStack();
|
||||
|
||||
mThat.mCxxStackFrames.push_back(RPCFrame(direction, msg));
|
||||
mThat.mSawRPCOutMsg |= (direction == OUT_MESSAGE) &&
|
||||
(msg->is_rpc());
|
||||
const RPCFrame& frame = mThat.mCxxStackFrames.back();
|
||||
|
||||
if (frame.IsRPCIncall())
|
||||
mThat.EnteredCall();
|
||||
|
||||
mThat.mSawRPCOutMsg |= frame.IsRPCOutcall();
|
||||
}
|
||||
|
||||
~CxxStackFrame() {
|
||||
bool exitingCall = mThat.mCxxStackFrames.back().IsRPCIncall();
|
||||
mThat.mCxxStackFrames.pop_back();
|
||||
bool exitingStack = mThat.mCxxStackFrames.empty();
|
||||
|
||||
|
@ -244,6 +279,9 @@ protected:
|
|||
return;
|
||||
|
||||
mThat.AssertWorkerThread();
|
||||
if (exitingCall)
|
||||
mThat.ExitedCall();
|
||||
|
||||
if (exitingStack)
|
||||
mThat.ExitedCxxStack();
|
||||
}
|
||||
|
|
|
@ -1408,6 +1408,14 @@ class Protocol(ipdl.ast.Protocol):
|
|||
assert self.decl.type.isToplevel()
|
||||
return ExprVar('ExitedCxxStack')
|
||||
|
||||
def enteredCallVar(self):
|
||||
assert self.decl.type.isToplevel()
|
||||
return ExprVar('EnteredCall')
|
||||
|
||||
def exitedCallVar(self):
|
||||
assert self.decl.type.isToplevel()
|
||||
return ExprVar('ExitedCall')
|
||||
|
||||
def onCxxStackVar(self):
|
||||
assert self.decl.type.isToplevel()
|
||||
return ExprVar('IsOnCxxStack')
|
||||
|
@ -2709,13 +2717,19 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
ret=Type.BOOL, virtual=1))
|
||||
shouldcontinue.addstmt(StmtReturn(ExprLiteral.TRUE))
|
||||
|
||||
# void EnteredCxxStack(); default to no-op
|
||||
# void Entered*()/Exited*(); default to no-op
|
||||
entered = MethodDefn(
|
||||
MethodDecl(p.enteredCxxStackVar().name, virtual=1))
|
||||
exited = MethodDefn(
|
||||
MethodDecl(p.exitedCxxStackVar().name, virtual=1))
|
||||
enteredcall = MethodDefn(
|
||||
MethodDecl(p.enteredCallVar().name, virtual=1))
|
||||
exitedcall = MethodDefn(
|
||||
MethodDecl(p.exitedCallVar().name, virtual=1))
|
||||
|
||||
self.cls.addstmts([ shouldcontinue, entered, exited,
|
||||
self.cls.addstmts([ shouldcontinue,
|
||||
entered, exited,
|
||||
enteredcall, exitedcall,
|
||||
Whitespace.NL ])
|
||||
|
||||
self.cls.addstmts((
|
||||
|
@ -2950,13 +2964,23 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
onexited = MethodDefn(MethodDecl('OnExitedCxxStack'))
|
||||
onexited.addstmt(StmtReturn(ExprCall(p.exitedCxxStackVar())))
|
||||
|
||||
# OnEnteredCxxStack()
|
||||
onenteredcall = MethodDefn(MethodDecl('OnEnteredCall'))
|
||||
onenteredcall.addstmt(StmtReturn(ExprCall(p.enteredCallVar())))
|
||||
|
||||
# OnExitedCxxStack()
|
||||
onexitedcall = MethodDefn(MethodDecl('OnExitedCall'))
|
||||
onexitedcall.addstmt(StmtReturn(ExprCall(p.exitedCallVar())))
|
||||
|
||||
# bool IsOnCxxStack()
|
||||
onstack = MethodDefn(
|
||||
MethodDecl(p.onCxxStackVar().name, ret=Type.BOOL, const=1))
|
||||
onstack.addstmt(StmtReturn(ExprCall(
|
||||
ExprSelect(p.channelVar(), '.', p.onCxxStackVar().name))))
|
||||
|
||||
self.cls.addstmts([ onentered, onexited, onstack, Whitespace.NL ])
|
||||
self.cls.addstmts([ onentered, onexited,
|
||||
onenteredcall, onexitedcall,
|
||||
onstack, Whitespace.NL ])
|
||||
|
||||
# OnChannelClose()
|
||||
onclose = MethodDefn(MethodDecl('OnChannelClose'))
|
||||
|
|
|
@ -10,7 +10,8 @@ namespace _ipdltest {
|
|||
//-----------------------------------------------------------------------------
|
||||
// parent
|
||||
|
||||
TestStackHooksParent::TestStackHooksParent() : mOnStack(false)
|
||||
TestStackHooksParent::TestStackHooksParent() :
|
||||
mOnStack(false), mIncallDepth(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestStackHooksParent);
|
||||
}
|
||||
|
@ -40,6 +41,9 @@ TestStackHooksParent::AnswerStackFrame()
|
|||
if (!mOnStack)
|
||||
fail("not on C++ stack?!");
|
||||
|
||||
if (1 != mIncallDepth)
|
||||
fail("missed EnteredCall or ExitedCall hook");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -49,7 +53,8 @@ TestStackHooksParent::AnswerStackFrame()
|
|||
TestStackHooksChild::TestStackHooksChild() :
|
||||
mOnStack(false),
|
||||
mEntered(0),
|
||||
mExited(0)
|
||||
mExited(0),
|
||||
mIncallDepth(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestStackHooksChild);
|
||||
}
|
||||
|
@ -71,6 +76,9 @@ TestStackHooksChild::RecvStart()
|
|||
if (!mOnStack)
|
||||
fail("missed stack notification");
|
||||
|
||||
if (0 != mIncallDepth)
|
||||
fail("EnteredCall/ExitedCall malfunction");
|
||||
|
||||
// kick off tests from a runnable so that we can start with
|
||||
// RPCChannel code on the C++ stack
|
||||
MessageLoop::current()->PostTask(FROM_HERE,
|
||||
|
@ -85,12 +93,15 @@ TestStackHooksChild::AnswerStackFrame()
|
|||
if (!mOnStack)
|
||||
fail("missed stack notification");
|
||||
|
||||
if (1 != mIncallDepth)
|
||||
fail("missed EnteredCall or ExitedCall hook");
|
||||
|
||||
// FIXME use IPDL state instead
|
||||
if (4 == mEntered) {
|
||||
if (4 == mEntered) { // test 4
|
||||
if (!SendAsync())
|
||||
fail("sending Async()");
|
||||
}
|
||||
else if (5 == mEntered) {
|
||||
else if (5 == mEntered) { // test 5
|
||||
if (!SendSync())
|
||||
fail("sending Sync()");
|
||||
}
|
||||
|
@ -112,11 +123,15 @@ TestStackHooksChild::RunTests()
|
|||
fail("missed stack notification");
|
||||
if (mOnStack)
|
||||
fail("spurious stack notification");
|
||||
if (0 != mIncallDepth)
|
||||
fail("EnteredCall/ExitedCall malfunction");
|
||||
|
||||
if (!SendAsync())
|
||||
fail("sending Async()");
|
||||
if (mOnStack)
|
||||
fail("spurious stack notification");
|
||||
if (0 != mIncallDepth)
|
||||
fail("EnteredCall/ExitedCall malfunction");
|
||||
if (2 != mEntered)
|
||||
fail("missed stack notification");
|
||||
|
||||
|
@ -124,6 +139,8 @@ TestStackHooksChild::RunTests()
|
|||
fail("sending Sync()");
|
||||
if (mOnStack)
|
||||
fail("spurious stack notification");
|
||||
if (0 != mIncallDepth)
|
||||
fail("EnteredCall/ExitedCall malfunction");
|
||||
if (3 != mEntered)
|
||||
fail("missed stack notification");
|
||||
|
||||
|
@ -131,6 +148,8 @@ TestStackHooksChild::RunTests()
|
|||
fail("calling RPC()");
|
||||
if (mOnStack)
|
||||
fail("spurious stack notification");
|
||||
if (0 != mIncallDepth)
|
||||
fail("EnteredCall/ExitedCall malfunction");
|
||||
if (4 != mEntered)
|
||||
fail("missed stack notification");
|
||||
|
||||
|
@ -138,6 +157,8 @@ TestStackHooksChild::RunTests()
|
|||
fail("calling StackFrame()");
|
||||
if (mOnStack)
|
||||
fail("spurious stack notification");
|
||||
if (0 != mIncallDepth)
|
||||
fail("EnteredCall/ExitedCall malfunction");
|
||||
if (5 != mEntered)
|
||||
fail("missed stack notification");
|
||||
|
||||
|
|
|
@ -62,8 +62,18 @@ protected:
|
|||
mOnStack = false;
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void EnteredCall() {
|
||||
++mIncallDepth;
|
||||
}
|
||||
NS_OVERRIDE
|
||||
virtual void ExitedCall() {
|
||||
--mIncallDepth;
|
||||
}
|
||||
|
||||
private:
|
||||
bool mOnStack;
|
||||
int mIncallDepth;
|
||||
};
|
||||
|
||||
|
||||
|
@ -109,10 +119,20 @@ protected:
|
|||
mOnStack = false;
|
||||
}
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void EnteredCall() {
|
||||
++mIncallDepth;
|
||||
}
|
||||
NS_OVERRIDE
|
||||
virtual void ExitedCall() {
|
||||
--mIncallDepth;
|
||||
}
|
||||
|
||||
private:
|
||||
bool mOnStack;
|
||||
int mEntered;
|
||||
int mExited;
|
||||
int mIncallDepth;
|
||||
};
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче