Bug 1044322 - Reset the channel listener on the correct thread, r=bsmedberg.

This commit is contained in:
Ben Turner 2014-08-08 18:19:33 -07:00
parent 877a0ecdc1
commit 3bd6fe6f31
2 changed files with 29 additions and 11 deletions

View File

@ -15,6 +15,7 @@
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#endif #endif
#include "mozilla/Assertions.h"
#include "nsDebug.h" #include "nsDebug.h"
#include "nsISupportsImpl.h" #include "nsISupportsImpl.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
@ -58,25 +59,26 @@ MessageLink::MessageLink(MessageChannel *aChan)
MessageLink::~MessageLink() MessageLink::~MessageLink()
{ {
#ifdef DEBUG
mChan = nullptr; mChan = nullptr;
#endif
} }
ProcessLink::ProcessLink(MessageChannel *aChan) ProcessLink::ProcessLink(MessageChannel *aChan)
: MessageLink(aChan), : MessageLink(aChan)
mExistingListener(nullptr) , mTransport(nullptr)
, mIOLoop(nullptr)
, mExistingListener(nullptr)
{ {
} }
ProcessLink::~ProcessLink() ProcessLink::~ProcessLink()
{ {
mIOLoop = 0; #ifdef DEBUG
if (mTransport) { mTransport = nullptr;
mTransport->set_listener(0); mIOLoop = nullptr;
mExistingListener = nullptr;
// we only hold a weak ref to the transport, which is "owned" #endif
// by GeckoChildProcess/GeckoThread
mTransport = 0;
}
} }
void void
@ -291,7 +293,8 @@ ProcessLink::OnEchoMessage(Message* msg)
void void
ProcessLink::OnChannelOpened() ProcessLink::OnChannelOpened()
{ {
mChan->AssertLinkThread(); AssertIOThread();
{ {
MonitorAutoLock lock(*mChan->mMonitor); MonitorAutoLock lock(*mChan->mMonitor);
@ -356,7 +359,11 @@ void
ProcessLink::OnChannelError() ProcessLink::OnChannelError()
{ {
AssertIOThread(); AssertIOThread();
MonitorAutoLock lock(*mChan->mMonitor); MonitorAutoLock lock(*mChan->mMonitor);
MOZ_ALWAYS_TRUE(this == mTransport->set_listener(mExistingListener));
mChan->OnChannelErrorFromLink(); mChan->OnChannelErrorFromLink();
} }
@ -368,6 +375,9 @@ ProcessLink::OnCloseChannel()
mTransport->Close(); mTransport->Close();
MonitorAutoLock lock(*mChan->mMonitor); MonitorAutoLock lock(*mChan->mMonitor);
MOZ_ALWAYS_TRUE(this == mTransport->set_listener(mExistingListener));
mChan->mChannelState = ChannelClosed; mChan->mChannelState = ChannelClosed;
mChan->mMonitor->Notify(); mChan->mMonitor->Notify();
} }

View File

@ -141,6 +141,14 @@ class ProcessLink
public: public:
explicit ProcessLink(MessageChannel *chan); explicit ProcessLink(MessageChannel *chan);
virtual ~ProcessLink(); 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); void Open(Transport* aTransport, MessageLoop *aIOLoop, Side aSide);
// Run on the I/O thread, only when using inter-process link. // Run on the I/O thread, only when using inter-process link.