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:
@@ -488,8 +488,10 @@ private:
|
|||||||
nsAutoPtr<IPC::Message> mReply;
|
nsAutoPtr<IPC::Message> mReply;
|
||||||
};
|
};
|
||||||
|
|
||||||
MessageChannel::MessageChannel(IToplevelProtocol *aListener)
|
MessageChannel::MessageChannel(const char* aName,
|
||||||
: mListener(aListener),
|
IToplevelProtocol *aListener)
|
||||||
|
: mName(aName),
|
||||||
|
mListener(aListener),
|
||||||
mChannelState(ChannelClosed),
|
mChannelState(ChannelClosed),
|
||||||
mSide(UnknownSide),
|
mSide(UnknownSide),
|
||||||
mLink(nullptr),
|
mLink(nullptr),
|
||||||
@@ -627,6 +629,18 @@ MessageChannel::CanSend() const
|
|||||||
return Connected();
|
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
|
void
|
||||||
MessageChannel::Clear()
|
MessageChannel::Clear()
|
||||||
{
|
{
|
||||||
@@ -644,6 +658,10 @@ MessageChannel::Clear()
|
|||||||
gParentProcessBlocker = nullptr;
|
gParentProcessBlocker = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mWorkerLoop) {
|
||||||
|
mWorkerLoop->RemoveDestructionObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
mWorkerLoop = nullptr;
|
mWorkerLoop = nullptr;
|
||||||
delete mLink;
|
delete mLink;
|
||||||
mLink = nullptr;
|
mLink = nullptr;
|
||||||
@@ -676,6 +694,8 @@ MessageChannel::Open(Transport* aTransport, MessageLoop* aIOLoop, Side aSide)
|
|||||||
mWorkerLoop = MessageLoop::current();
|
mWorkerLoop = MessageLoop::current();
|
||||||
mWorkerLoopID = mWorkerLoop->id();
|
mWorkerLoopID = mWorkerLoop->id();
|
||||||
|
|
||||||
|
mWorkerLoop->AddDestructionObserver(this);
|
||||||
|
|
||||||
ProcessLink *link = new ProcessLink(this);
|
ProcessLink *link = new ProcessLink(this);
|
||||||
link->Open(aTransport, aIOLoop, aSide); // :TODO: n.b.: sets mChild
|
link->Open(aTransport, aIOLoop, aSide); // :TODO: n.b.: sets mChild
|
||||||
mLink = link;
|
mLink = link;
|
||||||
@@ -752,6 +772,7 @@ MessageChannel::CommonThreadOpenInit(MessageChannel *aTargetChan, Side aSide)
|
|||||||
{
|
{
|
||||||
mWorkerLoop = MessageLoop::current();
|
mWorkerLoop = MessageLoop::current();
|
||||||
mWorkerLoopID = mWorkerLoop->id();
|
mWorkerLoopID = mWorkerLoop->id();
|
||||||
|
mWorkerLoop->AddDestructionObserver(this);
|
||||||
mLink = new ThreadLink(this, aTargetChan);
|
mLink = new ThreadLink(this, aTargetChan);
|
||||||
mSide = aSide;
|
mSide = aSide;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ enum ChannelState {
|
|||||||
|
|
||||||
class AutoEnterTransaction;
|
class AutoEnterTransaction;
|
||||||
|
|
||||||
class MessageChannel : HasResultCodes
|
class MessageChannel : HasResultCodes, MessageLoop::DestructionObserver
|
||||||
{
|
{
|
||||||
friend class ProcessLink;
|
friend class ProcessLink;
|
||||||
friend class ThreadLink;
|
friend class ThreadLink;
|
||||||
@@ -89,7 +89,8 @@ class MessageChannel : HasResultCodes
|
|||||||
typedef IPC::MessageInfo MessageInfo;
|
typedef IPC::MessageInfo MessageInfo;
|
||||||
typedef mozilla::ipc::Transport Transport;
|
typedef mozilla::ipc::Transport Transport;
|
||||||
|
|
||||||
explicit MessageChannel(IToplevelProtocol *aListener);
|
explicit MessageChannel(const char *aName,
|
||||||
|
IToplevelProtocol *aListener);
|
||||||
~MessageChannel();
|
~MessageChannel();
|
||||||
|
|
||||||
IToplevelProtocol *Listener() const {
|
IToplevelProtocol *Listener() const {
|
||||||
@@ -491,7 +492,12 @@ class MessageChannel : HasResultCodes
|
|||||||
typedef std::map<size_t, Message> MessageMap;
|
typedef std::map<size_t, Message> MessageMap;
|
||||||
typedef IPC::Message::msgid_t msgid_t;
|
typedef IPC::Message::msgid_t msgid_t;
|
||||||
|
|
||||||
|
void WillDestroyCurrentMessageLoop() override;
|
||||||
|
|
||||||
private:
|
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,
|
// Based on presumption the listener owns and overlives the channel,
|
||||||
// this is never nullified.
|
// this is never nullified.
|
||||||
IToplevelProtocol* mListener;
|
IToplevelProtocol* mListener;
|
||||||
|
|||||||
@@ -2668,6 +2668,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||||||
ExprMemberInit(ExprVar('mozilla::ipc::IToplevelProtocol'),
|
ExprMemberInit(ExprVar('mozilla::ipc::IToplevelProtocol'),
|
||||||
[_protocolId(ptype), side]),
|
[_protocolId(ptype), side]),
|
||||||
ExprMemberInit(p.channelVar(), [
|
ExprMemberInit(p.channelVar(), [
|
||||||
|
ExprLiteral.String(_actorName(p.name, self.side)),
|
||||||
ExprCall(ExprVar('ALLOW_THIS_IN_INITIALIZER_LIST'),
|
ExprCall(ExprVar('ALLOW_THIS_IN_INITIALIZER_LIST'),
|
||||||
[ ExprVar.THIS ]) ]),
|
[ ExprVar.THIS ]) ]),
|
||||||
ExprMemberInit(p.stateVar(),
|
ExprMemberInit(p.stateVar(),
|
||||||
|
|||||||
Reference in New Issue
Block a user