mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 540004, part 3: Add a ShouldContinue() interface to IPDL actors that allows them to decide how a hang should be treated. r=bent
--HG-- extra : transplant_source : m%5E%40%9FYJ%EFI%9F%E5%25s%8E%1A%AF%BEQ%01va
This commit is contained in:
parent
3ea312dfdf
commit
feb0d735b0
@ -61,6 +61,7 @@ public:
|
||||
virtual void OnChannelClose() = 0;
|
||||
virtual void OnChannelError() = 0;
|
||||
virtual Result OnMessageReceived(const Message& aMessage) = 0;
|
||||
virtual bool OnReplyTimeout() = 0;
|
||||
virtual Result OnMessageReceived(const Message& aMessage,
|
||||
Message*& aReply) = 0;
|
||||
virtual Result OnCallReceived(const Message& aMessage,
|
||||
|
@ -237,7 +237,11 @@ SyncChannel::ShouldContinueFromTimeout()
|
||||
AssertWorkerThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
|
||||
bool cont = true;
|
||||
bool cont;
|
||||
{
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
cont = static_cast<SyncListener*>(mListener)->OnReplyTimeout();
|
||||
}
|
||||
|
||||
if (!cont) {
|
||||
// NB: there's a sublety here. If parents were allowed to
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
virtual void OnChannelClose() = 0;
|
||||
virtual void OnChannelError() = 0;
|
||||
virtual Result OnMessageReceived(const Message& aMessage) = 0;
|
||||
virtual bool OnReplyTimeout() = 0;
|
||||
virtual Result OnMessageReceived(const Message& aMessage,
|
||||
Message*& aReply) = 0;
|
||||
};
|
||||
@ -81,6 +82,11 @@ public:
|
||||
// Synchronously send |msg| (i.e., wait for |reply|)
|
||||
bool Send(Message* msg, Message* reply);
|
||||
|
||||
void SetReplyTimeoutMs(int32 aTimeoutMs) {
|
||||
AssertWorkerThread();
|
||||
mTimeoutMs = (aTimeoutMs <= 0) ? kNoTimeout : aTimeoutMs;
|
||||
}
|
||||
|
||||
// Override the AsyncChannel handler so we can dispatch sync messages
|
||||
NS_OVERRIDE virtual void OnMessageReceived(const Message& msg);
|
||||
NS_OVERRIDE virtual void OnChannelError();
|
||||
|
@ -342,6 +342,7 @@ Any type, naked or pointer, can be const (const T) or ref (T&).
|
||||
T=copy.deepcopy(self.T, memo))
|
||||
Type.BOOL = Type('bool')
|
||||
Type.INT = Type('int')
|
||||
Type.INT32 = Type('int32')
|
||||
Type.INTPTR = Type('intptr_t')
|
||||
Type.UINT32 = Type('uint32')
|
||||
Type.SIZE = Type('size_t')
|
||||
|
@ -1344,6 +1344,10 @@ class Protocol(ipdl.ast.Protocol):
|
||||
def otherProcessMethod(self):
|
||||
return ExprVar('OtherProcess')
|
||||
|
||||
def shouldContinueFromTimeoutVar(self):
|
||||
assert self.decl.type.isToplevel()
|
||||
return ExprVar('ShouldContinueFromReplyTimeout')
|
||||
|
||||
def nextActorIdExpr(self, side):
|
||||
assert self.decl.type.isToplevel()
|
||||
if side is 'parent': op = '++'
|
||||
@ -2629,6 +2633,14 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
Whitespace.NL
|
||||
])
|
||||
|
||||
if ptype.isToplevel():
|
||||
# bool ShouldContinueFromReplyTimeout(); default to |true|
|
||||
shouldcontinue = MethodDefn(
|
||||
MethodDecl(p.shouldContinueFromTimeoutVar().name,
|
||||
ret=Type.BOOL, virtual=1))
|
||||
shouldcontinue.addstmt(StmtReturn(ExprLiteral.TRUE))
|
||||
self.cls.addstmts([ shouldcontinue, Whitespace.NL ])
|
||||
|
||||
self.cls.addstmts((
|
||||
[ Label.PRIVATE ]
|
||||
+ self.standardTypedefs()
|
||||
@ -2698,6 +2710,18 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
ExprCall(ExprSelect(p.channelVar(), '.', 'Close'))))
|
||||
self.cls.addstmts([ closemeth, Whitespace.NL ])
|
||||
|
||||
if ptype.talksSync() or ptype.talksRpc():
|
||||
# SetReplyTimeoutMs()
|
||||
timeoutvar = ExprVar('aTimeoutMs')
|
||||
settimeout = MethodDefn(MethodDecl(
|
||||
'SetReplyTimeoutMs',
|
||||
params=[ Decl(Type.INT32, timeoutvar.name) ]))
|
||||
settimeout.addstmt(StmtExpr(
|
||||
ExprCall(
|
||||
ExprSelect(p.channelVar(), '.', 'SetReplyTimeoutMs'),
|
||||
args=[ timeoutvar ])))
|
||||
self.cls.addstmts([ settimeout, Whitespace.NL ])
|
||||
|
||||
if not ptype.isToplevel():
|
||||
if 1 == len(p.managers):
|
||||
## manager()
|
||||
@ -2820,6 +2844,22 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
destroysubtreevar = ExprVar('DestroySubtree')
|
||||
deallocsubtreevar = ExprVar('DeallocSubtree')
|
||||
|
||||
# OnReplyTimeout()
|
||||
if toplevel.talksSync() or toplevel.talksRpc():
|
||||
ontimeout = MethodDefn(
|
||||
MethodDecl('OnReplyTimeout', ret=Type.BOOL))
|
||||
|
||||
if ptype.isToplevel():
|
||||
ontimeout.addstmt(StmtReturn(
|
||||
ExprCall(p.shouldContinueFromTimeoutVar())))
|
||||
else:
|
||||
ontimeout.addstmts([
|
||||
_runtimeAbort("`OnReplyTimeout' called on non-toplevel actor"),
|
||||
StmtReturn(ExprLiteral.FALSE)
|
||||
])
|
||||
|
||||
self.cls.addstmts([ ontimeout, Whitespace.NL ])
|
||||
|
||||
# OnChannelClose()
|
||||
onclose = MethodDefn(MethodDecl('OnChannelClose'))
|
||||
if ptype.isToplevel():
|
||||
|
Loading…
Reference in New Issue
Block a user