Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1768)

Side by Side Diff: ipc/ipc_sync_message_filter.cc

Issue 1601005: Allow synchronous messages to be sent from threads other than the main thread... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ipc/ipc_sync_message_filter.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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.
4
5 #include "ipc/ipc_sync_message_filter.h"
6
7 #include "base/logging.h"
8 #include "base/message_loop.h"
9 #include "ipc/ipc_sync_message.h"
10
11 namespace IPC {
12
13 SyncMessageFilter::SyncMessageFilter(base::WaitableEvent* shutdown_event)
14 : channel_(NULL),
15 listener_loop_(MessageLoop::current()),
16 io_loop_(NULL),
17 shutdown_event_(shutdown_event) {
18 }
19
20 SyncMessageFilter::~SyncMessageFilter() {
21 }
22
23 bool SyncMessageFilter::Send(Message* message) {
24 {
25 AutoLock auto_lock(lock_);
26 if (!io_loop_) {
27 delete message;
28 return false;
29 }
30 }
31
32 if (!message->is_sync()) {
33 io_loop_->PostTask(
34 FROM_HERE,
35 NewRunnableMethod(this, &SyncMessageFilter::SendOnIOThread, message));
36 return true;
37 }
38
39 base::WaitableEvent done_event(true, false);
40 PendingSyncMsg pending_message(
41 SyncMessage::GetMessageId(*message),
42 reinterpret_cast<SyncMessage*>(message)->GetReplyDeserializer(),
43 &done_event);
44
45 {
46 AutoLock auto_lock(lock_);
47 // Can't use this class on the main thread or else it can lead to deadlocks.
48 // Also by definition, can't use this on IO thread since we're blocking it.
49 DCHECK(MessageLoop::current() != listener_loop_);
50 DCHECK(MessageLoop::current() != io_loop_);
51 pending_sync_messages_[MessageLoop::current()] = &pending_message;
52 }
53
54 io_loop_->PostTask(
55 FROM_HERE,
56 NewRunnableMethod(this, &SyncMessageFilter::SendOnIOThread, message));
57
58 base::WaitableEvent* events[2] = { shutdown_event_, &done_event };
59 base::WaitableEvent::WaitMany(events, 2);
60
61 {
62 AutoLock auto_lock(lock_);
63 delete pending_message.deserializer;
64 pending_sync_messages_.erase(MessageLoop::current());
65 }
66
67 return pending_message.send_result;
68 }
69
70 void SyncMessageFilter::SendOnIOThread(Message* message) {
71 if (channel_) {
72 channel_->Send(message);
73 return;
74 }
75
76 if (message->is_sync()) {
77 // We don't know which thread sent it, but it doesn't matter, just signal
78 // them all.
79 SignalAllEvents();
80 }
81
82 delete message;
83 }
84
85 void SyncMessageFilter::SignalAllEvents() {
86 AutoLock auto_lock(lock_);
87 for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin();
88 iter != pending_sync_messages_.end(); ++iter) {
89 iter->second->done_event->Signal();
90 }
91 }
92
93 void SyncMessageFilter::OnFilterAdded(Channel* channel) {
94 channel_ = channel;
95 AutoLock auto_lock(lock_);
96 io_loop_ = MessageLoop::current();
97 }
98
99 void SyncMessageFilter::OnChannelError() {
100 channel_ = NULL;
101 SignalAllEvents();
102 }
103
104 void SyncMessageFilter::OnChannelClosing() {
105 channel_ = NULL;
106 SignalAllEvents();
107 }
108
109 bool SyncMessageFilter::OnMessageReceived(const Message& message) {
110 AutoLock auto_lock(lock_);
111 for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin();
112 iter != pending_sync_messages_.end(); ++iter) {
113 if (SyncMessage::IsMessageReplyTo(message, iter->second->id)) {
114 if (!message.is_reply_error()) {
115 iter->second->send_result =
116 iter->second->deserializer->SerializeOutputParameters(message);
117 }
118 iter->second->done_event->Signal();
119 return true;
120 }
121 }
122
123 return false;
124 }
125
126 } // namespace IPC
OLDNEW
« no previous file with comments | « ipc/ipc_sync_message_filter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698