Bug 535298: Cancel the NotifyMaybeChannelError event if the AsyncChannel is destroyed, and allow AsyncChannel::Close() to be called after a channel error (e.g. child process crash). r=cjones

This commit is contained in:
Benjamin Smedberg 2009-12-17 18:12:03 -06:00
Родитель a7490ef84a
Коммит 447ac2b560
2 изменённых файлов: 15 добавлений и 4 удалений

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

@ -64,7 +64,8 @@ AsyncChannel::AsyncChannel(AsyncListener* aListener)
mMutex("mozilla.ipc.AsyncChannel.mMutex"),
mCvar(mMutex, "mozilla.ipc.AsyncChannel.mCvar"),
mIOLoop(),
mWorkerLoop()
mWorkerLoop(),
mChannelErrorTask(NULL)
{
MOZ_COUNT_CTOR(AsyncChannel);
}
@ -129,6 +130,9 @@ AsyncChannel::Close()
{
MutexAutoLock lock(mMutex);
if (ChannelError == mChannelState)
return;
if (ChannelConnected != mChannelState)
// XXX be strict about this until there's a compelling reason
// to relax
@ -295,6 +299,10 @@ AsyncChannel::Clear()
// by GeckoChildProcess/GeckoThread
mTransport = 0;
}
if (mChannelErrorTask) {
mChannelErrorTask->Cancel();
mChannelErrorTask = NULL;
}
}
bool
@ -398,9 +406,11 @@ AsyncChannel::OnChannelError()
if (ChannelClosing != mChannelState)
mChannelState = ChannelError;
mWorkerLoop->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AsyncChannel::NotifyMaybeChannelError));
NS_ASSERTION(!mChannelErrorTask, "OnChannelError called twice?");
mChannelErrorTask =
NewRunnableMethod(this, &AsyncChannel::NotifyMaybeChannelError);
mWorkerLoop->PostTask(FROM_HERE, mChannelErrorTask);
}
void

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

@ -176,6 +176,7 @@ protected:
MessageLoop* mIOLoop; // thread where IO happens
MessageLoop* mWorkerLoop; // thread where work is done
bool mChild; // am I the child or parent?
CancelableTask* mChannelErrorTask; // NotifyMaybeChannelError runnable
};