Instrument how the download file chooser is used.
[chromium-blink-merge.git] / ipc / ipc_sync_message_filter.cc
blobe49ebd640cb8ef1b95f7db18ece2db033b968732
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ipc/ipc_sync_message_filter.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/message_loop_proxy.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "ipc/ipc_sync_message.h"
14 using base::MessageLoopProxy;
16 namespace IPC {
18 SyncMessageFilter::SyncMessageFilter(base::WaitableEvent* shutdown_event)
19 : channel_(NULL),
20 listener_loop_(MessageLoopProxy::current()),
21 shutdown_event_(shutdown_event) {
24 SyncMessageFilter::~SyncMessageFilter() {
27 bool SyncMessageFilter::Send(Message* message) {
29 base::AutoLock auto_lock(lock_);
30 if (!io_loop_) {
31 delete message;
32 return false;
36 if (!message->is_sync()) {
37 io_loop_->PostTask(
38 FROM_HERE, base::Bind(&SyncMessageFilter::SendOnIOThread, this, message));
39 return true;
42 base::WaitableEvent done_event(true, false);
43 PendingSyncMsg pending_message(
44 SyncMessage::GetMessageId(*message),
45 reinterpret_cast<SyncMessage*>(message)->GetReplyDeserializer(),
46 &done_event);
49 base::AutoLock auto_lock(lock_);
50 // Can't use this class on the main thread or else it can lead to deadlocks.
51 // Also by definition, can't use this on IO thread since we're blocking it.
52 DCHECK(MessageLoopProxy::current() != listener_loop_);
53 DCHECK(MessageLoopProxy::current() != io_loop_);
54 pending_sync_messages_.insert(&pending_message);
57 io_loop_->PostTask(
58 FROM_HERE, base::Bind(&SyncMessageFilter::SendOnIOThread, this, message));
60 base::WaitableEvent* events[2] = { shutdown_event_, &done_event };
61 base::WaitableEvent::WaitMany(events, 2);
64 base::AutoLock auto_lock(lock_);
65 delete pending_message.deserializer;
66 pending_sync_messages_.erase(&pending_message);
69 return pending_message.send_result;
72 void SyncMessageFilter::SendOnIOThread(Message* message) {
73 if (channel_) {
74 channel_->Send(message);
75 return;
78 if (message->is_sync()) {
79 // We don't know which thread sent it, but it doesn't matter, just signal
80 // them all.
81 SignalAllEvents();
84 delete message;
87 void SyncMessageFilter::SignalAllEvents() {
88 base::AutoLock auto_lock(lock_);
89 for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin();
90 iter != pending_sync_messages_.end(); ++iter) {
91 (*iter)->done_event->Signal();
95 void SyncMessageFilter::OnFilterAdded(Channel* channel) {
96 channel_ = channel;
97 base::AutoLock auto_lock(lock_);
98 io_loop_ = MessageLoopProxy::current();
101 void SyncMessageFilter::OnChannelError() {
102 channel_ = NULL;
103 SignalAllEvents();
106 void SyncMessageFilter::OnChannelClosing() {
107 channel_ = NULL;
108 SignalAllEvents();
111 bool SyncMessageFilter::OnMessageReceived(const Message& message) {
112 base::AutoLock auto_lock(lock_);
113 for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin();
114 iter != pending_sync_messages_.end(); ++iter) {
115 if (SyncMessage::IsMessageReplyTo(message, (*iter)->id)) {
116 if (!message.is_reply_error()) {
117 (*iter)->send_result =
118 (*iter)->deserializer->SerializeOutputParameters(message);
120 (*iter)->done_event->Signal();
121 return true;
125 return false;
128 } // namespace IPC