diff --git a/ipc/glue/MessageLink.cpp b/ipc/glue/MessageLink.cpp index 299902e131e1..868bde8021ca 100644 --- a/ipc/glue/MessageLink.cpp +++ b/ipc/glue/MessageLink.cpp @@ -15,6 +15,7 @@ #include "mozilla/Preferences.h" #endif +#include "mozilla/Assertions.h" #include "nsDebug.h" #include "nsISupportsImpl.h" #include "nsXULAppAPI.h" @@ -58,25 +59,26 @@ MessageLink::MessageLink(MessageChannel *aChan) MessageLink::~MessageLink() { +#ifdef DEBUG mChan = nullptr; +#endif } ProcessLink::ProcessLink(MessageChannel *aChan) - : MessageLink(aChan), - mExistingListener(nullptr) + : MessageLink(aChan) + , mTransport(nullptr) + , mIOLoop(nullptr) + , mExistingListener(nullptr) { } ProcessLink::~ProcessLink() { - mIOLoop = 0; - if (mTransport) { - mTransport->set_listener(0); - - // we only hold a weak ref to the transport, which is "owned" - // by GeckoChildProcess/GeckoThread - mTransport = 0; - } +#ifdef DEBUG + mTransport = nullptr; + mIOLoop = nullptr; + mExistingListener = nullptr; +#endif } void @@ -291,7 +293,8 @@ ProcessLink::OnEchoMessage(Message* msg) void ProcessLink::OnChannelOpened() { - mChan->AssertLinkThread(); + AssertIOThread(); + { MonitorAutoLock lock(*mChan->mMonitor); @@ -356,7 +359,11 @@ void ProcessLink::OnChannelError() { AssertIOThread(); + MonitorAutoLock lock(*mChan->mMonitor); + + MOZ_ALWAYS_TRUE(this == mTransport->set_listener(mExistingListener)); + mChan->OnChannelErrorFromLink(); } @@ -368,6 +375,9 @@ ProcessLink::OnCloseChannel() mTransport->Close(); MonitorAutoLock lock(*mChan->mMonitor); + + MOZ_ALWAYS_TRUE(this == mTransport->set_listener(mExistingListener)); + mChan->mChannelState = ChannelClosed; mChan->mMonitor->Notify(); } diff --git a/ipc/glue/MessageLink.h b/ipc/glue/MessageLink.h index 8203bc0d75fe..c069112f6c11 100644 --- a/ipc/glue/MessageLink.h +++ b/ipc/glue/MessageLink.h @@ -141,6 +141,14 @@ class ProcessLink public: explicit ProcessLink(MessageChannel *chan); virtual ~ProcessLink(); + + // The ProcessLink will register itself as the IPC::Channel::Listener on the + // transport passed here. If the transport already has a listener registered + // then a listener chain will be established (the ProcessLink listener + // methods will be called first and may call some methods on the original + // listener as well). Once the channel is closed (either via normal shutdown + // or a pipe error) the chain will be destroyed and the original listener + // will again be registered. void Open(Transport* aTransport, MessageLoop *aIOLoop, Side aSide); // Run on the I/O thread, only when using inter-process link.