Bug 1349699 - Assert when destroying a MessageLoop that a live MessageChannel is attached to (r=dvander)

MozReview-Commit-ID: GGr5UqJl3ui
This commit is contained in:
Bill McCloskey
2017-03-20 14:15:44 -07:00
parent 5162531982
commit 7aaaeb22ed
3 changed files with 32 additions and 4 deletions

View File

@@ -488,8 +488,10 @@ private:
nsAutoPtr<IPC::Message> mReply;
};
MessageChannel::MessageChannel(IToplevelProtocol *aListener)
: mListener(aListener),
MessageChannel::MessageChannel(const char* aName,
IToplevelProtocol *aListener)
: mName(aName),
mListener(aListener),
mChannelState(ChannelClosed),
mSide(UnknownSide),
mLink(nullptr),
@@ -627,6 +629,18 @@ MessageChannel::CanSend() const
return Connected();
}
void
MessageChannel::WillDestroyCurrentMessageLoop()
{
#if !defined(ANDROID)
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProtocolName"),
nsDependentCString(mName));
#endif
MOZ_CRASH("MessageLoop destroyed before MessageChannel that's bound to it");
#endif
}
void
MessageChannel::Clear()
{
@@ -644,6 +658,10 @@ MessageChannel::Clear()
gParentProcessBlocker = nullptr;
}
if (mWorkerLoop) {
mWorkerLoop->RemoveDestructionObserver(this);
}
mWorkerLoop = nullptr;
delete mLink;
mLink = nullptr;
@@ -676,6 +694,8 @@ MessageChannel::Open(Transport* aTransport, MessageLoop* aIOLoop, Side aSide)
mWorkerLoop = MessageLoop::current();
mWorkerLoopID = mWorkerLoop->id();
mWorkerLoop->AddDestructionObserver(this);
ProcessLink *link = new ProcessLink(this);
link->Open(aTransport, aIOLoop, aSide); // :TODO: n.b.: sets mChild
mLink = link;
@@ -752,6 +772,7 @@ MessageChannel::CommonThreadOpenInit(MessageChannel *aTargetChan, Side aSide)
{
mWorkerLoop = MessageLoop::current();
mWorkerLoopID = mWorkerLoop->id();
mWorkerLoop->AddDestructionObserver(this);
mLink = new ThreadLink(this, aTargetChan);
mSide = aSide;
}

View File

@@ -72,7 +72,7 @@ enum ChannelState {
class AutoEnterTransaction;
class MessageChannel : HasResultCodes
class MessageChannel : HasResultCodes, MessageLoop::DestructionObserver
{
friend class ProcessLink;
friend class ThreadLink;
@@ -89,7 +89,8 @@ class MessageChannel : HasResultCodes
typedef IPC::MessageInfo MessageInfo;
typedef mozilla::ipc::Transport Transport;
explicit MessageChannel(IToplevelProtocol *aListener);
explicit MessageChannel(const char *aName,
IToplevelProtocol *aListener);
~MessageChannel();
IToplevelProtocol *Listener() const {
@@ -491,7 +492,12 @@ class MessageChannel : HasResultCodes
typedef std::map<size_t, Message> MessageMap;
typedef IPC::Message::msgid_t msgid_t;
void WillDestroyCurrentMessageLoop() override;
private:
// This will be a string literal, so lifetime is not an issue.
const char* mName;
// Based on presumption the listener owns and overlives the channel,
// this is never nullified.
IToplevelProtocol* mListener;

View File

@@ -2668,6 +2668,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
ExprMemberInit(ExprVar('mozilla::ipc::IToplevelProtocol'),
[_protocolId(ptype), side]),
ExprMemberInit(p.channelVar(), [
ExprLiteral.String(_actorName(p.name, self.side)),
ExprCall(ExprVar('ALLOW_THIS_IN_INITIALIZER_LIST'),
[ ExprVar.THIS ]) ]),
ExprMemberInit(p.stateVar(),