Bug 1548717 - Part 2: Check CanSend before trying to send, r=froydnj

Differential Revision: https://phabricator.services.mozilla.com/D30236

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nika Layzell 2019-05-21 17:04:35 +00:00
parent 833e7d5780
commit 45a2a8e839
3 changed files with 61 additions and 12 deletions

View File

@ -599,6 +599,36 @@ already_AddRefed<nsIEventTarget> IProtocol::ManagedState::GetActorEventTarget(
return mProtocol->Manager()->GetActorEventTarget(aActor);
}
bool IProtocol::ChannelSend(IPC::Message* aMsg) {
UniquePtr<IPC::Message> msg(aMsg);
if (CanSend()) {
return GetIPCChannel()->Send(msg.release());
}
NS_WARNING("IPC message discarded: actor cannot send");
return false;
}
bool IProtocol::ChannelSend(IPC::Message* aMsg, IPC::Message* aReply) {
UniquePtr<IPC::Message> msg(aMsg);
if (CanSend()) {
return GetIPCChannel()->Send(msg.release(), aReply);
}
NS_WARNING("IPC message discarded: actor cannot send");
return false;
}
bool IProtocol::ChannelCall(IPC::Message* aMsg, IPC::Message* aReply) {
UniquePtr<IPC::Message> msg(aMsg);
if (CanSend()) {
return GetIPCChannel()->Call(msg.release(), aReply);
}
NS_WARNING("IPC message discarded: actor cannot send");
return false;
}
void IProtocol::ActorConnected() {
if (mLinkStatus != LinkStatus::Inactive) {
return;

View File

@ -389,6 +389,23 @@ class IProtocol : public HasResultCodes {
void SetManagerAndRegister(IProtocol* aManager);
void SetManagerAndRegister(IProtocol* aManager, int32_t aId);
// Helpers for calling `Send` on our underlying IPC channel.
bool ChannelSend(IPC::Message* aMsg);
bool ChannelSend(IPC::Message* aMsg, IPC::Message* aReply);
bool ChannelCall(IPC::Message* aMsg, IPC::Message* aReply);
template <typename Value>
void ChannelSend(IPC::Message* aMsg, ResolveCallback<Value>&& aResolve,
RejectCallback&& aReject) {
UniquePtr<IPC::Message> msg(aMsg);
if (CanSend()) {
GetIPCChannel()->Send(msg.release(), this, std::move(aResolve),
std::move(aReject));
} else {
NS_WARNING("IPC message discarded: actor cannot send");
aReject(ResponseRejectReason::SendError);
}
}
// Collect all actors managed by this object in an array. To make this safer
// to iterate, `ActorLifecycleProxy` references are returned rather than raw
// actor pointers.

View File

@ -4439,10 +4439,8 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
sendmsg = (self.setMessageFlags(md, self.replyvar, seqno=seqno)
+ [self.logMessage(md, self.replyvar, 'Sending reply '),
StmtDecl(Decl(Type.BOOL, sendok.name),
init=ExprCall(
ExprSelect(self.protocol.callGetChannel(),
'->', 'Send'),
args=[self.replyvar])),
init=ExprCall(ExprVar('ChannelSend'),
args=[self.replyvar])),
failifsendok])
if len(md.returns) > 1:
resolvedecl = Decl(_tuple([p.moveType(self.side) for p in md.returns],
@ -4704,10 +4702,11 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
stmts.append(Whitespace.NL)
# Generate the actual call expression.
send = ExprSelect(self.protocol.callGetChannel(actor), '->', 'Send')
send = ExprVar('ChannelSend')
if actor is not None:
send = ExprSelect(actor, '->', send.name)
if md.returns:
stmts.append(StmtExpr(ExprCall(send, args=[msgexpr,
ExprVar('this'),
ExprMove(resolvefn),
ExprMove(rejectfn)])))
retvar = None
@ -4719,6 +4718,12 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
return (retvar, stmts)
def sendBlocking(self, md, msgexpr, replyexpr, actor=None):
send = ExprVar('ChannelSend')
if md.decl.type.isInterrupt():
send = ExprVar('ChannelCall')
if actor is not None:
send = ExprSelect(actor, '->', send.name)
sendok = ExprVar('sendok__')
return (
sendok,
@ -4733,12 +4738,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
ExprLiteral.String(self.protocol.name + "::" +
md.prettyMsgName()),
ExprVar('OTHER')])),
StmtExpr(ExprAssn(sendok,
ExprCall(
ExprSelect(self.protocol.callGetChannel(actor),
'->',
_sendPrefix(md.decl.type)),
args=[msgexpr, ExprAddrOf(replyexpr)]))),
StmtExpr(ExprAssn(sendok, ExprCall(send,
args=[msgexpr,
ExprAddrOf(replyexpr)]))),
])
])
)