Bug 546035: Check if we're still connected before dispatching a received message. r=bsmedberg

This commit is contained in:
Chris Jones 2010-03-11 01:35:26 -06:00
Родитель 1a5eba7be7
Коммит 640d54d3d3
4 изменённых файлов: 52 добавлений и 27 удалений

Просмотреть файл

@ -247,13 +247,7 @@ AsyncChannel::OnDispatchMessage(const Message& msg)
bool
AsyncChannel::OnSpecialMessage(uint16 id, const Message& msg)
{
switch (id) {
case GOODBYE_MESSAGE_TYPE:
return ProcessGoodbyeMessage();
default:
return false;
}
return false;
}
void
@ -266,20 +260,6 @@ AsyncChannel::SendSpecialMessage(Message* msg)
NewRunnableMethod(this, &AsyncChannel::OnSend, msg));
}
bool
AsyncChannel::ProcessGoodbyeMessage()
{
MutexAutoLock lock(mMutex);
// TODO sort out Close() on this side racing with Close() on the
// other side
mChannelState = ChannelClosing;
printf("NOTE: %s process received `Goodbye', closing down\n",
mChild ? "child" : "parent");
return true;
}
void
AsyncChannel::NotifyChannelClosed()
{
@ -413,10 +393,13 @@ AsyncChannel::OnMessageReceived(const Message& msg)
AssertIOThread();
NS_ASSERTION(mChannelState != ChannelError, "Shouldn't get here!");
// wake up the worker, there's work to do
mWorkerLoop->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AsyncChannel::OnDispatchMessage, msg));
MutexAutoLock lock(mMutex);
if (!MaybeInterceptSpecialIOMessage(msg))
// wake up the worker, there's work to do
mWorkerLoop->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AsyncChannel::OnDispatchMessage, msg));
}
void
@ -477,6 +460,34 @@ AsyncChannel::OnCloseChannel()
mCvar.Notify();
}
bool
AsyncChannel::MaybeInterceptSpecialIOMessage(const Message& msg)
{
AssertIOThread();
mMutex.AssertCurrentThreadOwns();
if (MSG_ROUTING_NONE == msg.routing_id()
&& GOODBYE_MESSAGE_TYPE == msg.type()) {
ProcessGoodbyeMessage();
return true;
}
return false;
}
void
AsyncChannel::ProcessGoodbyeMessage()
{
AssertIOThread();
mMutex.AssertCurrentThreadOwns();
// TODO sort out Close() on this side racing with Close() on the
// other side
mChannelState = ChannelClosing;
printf("NOTE: %s process received `Goodbye', closing down\n",
mChild ? "child" : "parent");
}
} // namespace ipc
} // namespace mozilla

Просмотреть файл

@ -161,8 +161,6 @@ protected:
// Run on the worker thread
bool ProcessGoodbyeMessage();
void NotifyChannelClosed();
void NotifyMaybeChannelError();
@ -174,6 +172,11 @@ protected:
void OnSend(Message* aMsg);
void OnCloseChannel();
// Return true if |msg| is a special message targeted at the IO
// thread, in which case it shouldn't be delivered to the worker.
bool MaybeInterceptSpecialIOMessage(const Message& msg);
void ProcessGoodbyeMessage();
Transport* mTransport;
AsyncListener* mListener;
ChannelState mChannelState;

Просмотреть файл

@ -370,6 +370,11 @@ RPCChannel::OnMaybeDequeueOne()
{
MutexAutoLock lock(mMutex);
if (!Connected()) {
ReportConnectionError("RPCChannel");
return;
}
if (!mDeferred.empty())
return MaybeProcessDeferredIncall();
@ -634,6 +639,9 @@ RPCChannel::OnMessageReceived(const Message& msg)
AssertIOThread();
MutexAutoLock lock(mMutex);
if (MaybeInterceptSpecialIOMessage(msg))
return;
// regardless of the RPC stack, if we're awaiting a sync reply, we
// know that it needs to be immediately handled to unblock us.
if (AwaitingSyncReply() && msg.is_sync()) {

Просмотреть файл

@ -192,6 +192,9 @@ SyncChannel::OnMessageReceived(const Message& msg)
MutexAutoLock lock(mMutex);
if (MaybeInterceptSpecialIOMessage(msg))
return;
if (!AwaitingSyncReply()) {
// wake up the worker, there's work to do
mWorkerLoop->PostTask(