| Index: ipc/ipc_sync_channel.cc
|
| ===================================================================
|
| --- ipc/ipc_sync_channel.cc (revision 33329)
|
| +++ ipc/ipc_sync_channel.cc (working copy)
|
| @@ -343,10 +343,15 @@
|
| }
|
|
|
| void SyncChannel::SyncContext::OnWaitableEventSignaled(WaitableEvent* event) {
|
| - DCHECK(event == shutdown_event_);
|
| - // Process shut down before we can get a reply to a synchronous message.
|
| - // Cancel pending Send calls, which will end up setting the send done event.
|
| - CancelPendingSends();
|
| + if (event == shutdown_event_) {
|
| + // Process shut down before we can get a reply to a synchronous message.
|
| + // Cancel pending Send calls, which will end up setting the send done event.
|
| + CancelPendingSends();
|
| + } else {
|
| + // We got the reply, timed out or the process shutdown.
|
| + DCHECK(event == GetSendDoneEvent());
|
| + MessageLoop::current()->Quit();
|
| + }
|
| }
|
|
|
|
|
| @@ -408,16 +413,18 @@
|
| }
|
|
|
| // Wait for reply, or for any other incoming synchronous messages.
|
| - WaitForReply(pump_messages_event);
|
| + // *this* might get deleted, so only call static functions at this point.
|
| + WaitForReply(context, pump_messages_event);
|
|
|
| return context->Pop();
|
| }
|
|
|
| -void SyncChannel::WaitForReply(WaitableEvent* pump_messages_event) {
|
| +void SyncChannel::WaitForReply(
|
| + SyncContext* context, WaitableEvent* pump_messages_event) {
|
| while (true) {
|
| WaitableEvent* objects[] = {
|
| - sync_context()->GetDispatchEvent(),
|
| - sync_context()->GetSendDoneEvent(),
|
| + context->GetDispatchEvent(),
|
| + context->GetSendDoneEvent(),
|
| pump_messages_event
|
| };
|
|
|
| @@ -426,22 +433,22 @@
|
| if (result == 0 /* dispatch event */) {
|
| // We're waiting for a reply, but we received a blocking synchronous
|
| // call. We must process it or otherwise a deadlock might occur.
|
| - sync_context()->GetDispatchEvent()->Reset();
|
| - sync_context()->DispatchMessages();
|
| + context->GetDispatchEvent()->Reset();
|
| + context->DispatchMessages();
|
| continue;
|
| }
|
|
|
| if (result == 2 /* pump_messages_event */)
|
| - WaitForReplyWithNestedMessageLoop(); // Start a nested message loop.
|
| + WaitForReplyWithNestedMessageLoop(context); // Run a nested message loop.
|
|
|
| break;
|
| }
|
| }
|
|
|
| -void SyncChannel::WaitForReplyWithNestedMessageLoop() {
|
| +void SyncChannel::WaitForReplyWithNestedMessageLoop(SyncContext* context) {
|
| base::WaitableEventWatcher send_done_watcher;
|
|
|
| - ReceivedSyncMsgQueue* sync_msg_queue = sync_context()->received_sync_msgs();
|
| + ReceivedSyncMsgQueue* sync_msg_queue = context->received_sync_msgs();
|
| DCHECK(sync_msg_queue != NULL);
|
|
|
| base::WaitableEventWatcher* old_send_done_event_watcher =
|
| @@ -461,7 +468,7 @@
|
|
|
| sync_msg_queue->set_top_send_done_watcher(&send_done_watcher);
|
|
|
| - send_done_watcher.StartWatching(sync_context()->GetSendDoneEvent(), this);
|
| + send_done_watcher.StartWatching(context->GetSendDoneEvent(), context);
|
| bool old_state = MessageLoop::current()->NestableTasksAllowed();
|
|
|
| MessageLoop::current()->SetNestableTasksAllowed(true);
|
| @@ -475,18 +482,12 @@
|
| }
|
|
|
| void SyncChannel::OnWaitableEventSignaled(WaitableEvent* event) {
|
| - WaitableEvent* dispatch_event = sync_context()->GetDispatchEvent();
|
| - if (event == dispatch_event) {
|
| - // The call to DispatchMessages might delete this object, so reregister
|
| - // the object watcher first.
|
| - dispatch_event->Reset();
|
| - dispatch_watcher_.StartWatching(dispatch_event, this);
|
| - sync_context()->DispatchMessages();
|
| - } else {
|
| - // We got the reply, timed out or the process shutdown.
|
| - DCHECK(event == sync_context()->GetSendDoneEvent());
|
| - MessageLoop::current()->Quit();
|
| - }
|
| + DCHECK(event == sync_context()->GetDispatchEvent());
|
| + // The call to DispatchMessages might delete this object, so reregister
|
| + // the object watcher first.
|
| + event->Reset();
|
| + dispatch_watcher_.StartWatching(event, this);
|
| + sync_context()->DispatchMessages();
|
| }
|
|
|
| } // namespace IPC
|
|
|