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