From 3bd6fe6f31f6f7154f9d517e83a473afcab76b63 Mon Sep 17 00:00:00 2001 From: Ben Turner Date: Fri, 8 Aug 2014 18:19:33 -0700 Subject: [PATCH] Bug 1044322 - Reset the channel listener on the correct thread, r=bsmedberg. --- ipc/glue/MessageLink.cpp | 32 +++++++++++++++++++++----------- ipc/glue/MessageLink.h | 8 ++++++++ 2 files changed, 29 insertions(+), 11 deletions(-) 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.