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

Side by Side Diff: ipc/ipc_sync_message_filter.cc

Issue 2077653002: Revert IPC SyncChannel to base::WaitableEvent waiting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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
« 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')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ipc/ipc_sync_message_filter.h" 5 #include "ipc/ipc_sync_message_filter.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
14 #include "base/synchronization/waitable_event.h" 11 #include "base/synchronization/waitable_event.h"
15 #include "base/threading/thread_task_runner_handle.h" 12 #include "base/threading/thread_task_runner_handle.h"
16 #include "ipc/ipc_channel.h" 13 #include "ipc/ipc_channel.h"
17 #include "ipc/ipc_sync_message.h" 14 #include "ipc/ipc_sync_message.h"
18 #include "ipc/mojo_event.h"
19 #include "mojo/public/cpp/bindings/sync_handle_registry.h"
20 15
21 namespace IPC { 16 namespace IPC {
22 17
23 namespace {
24
25 // A generic callback used when watching handles synchronously. Sets |*signal|
26 // to true. Also sets |*error| to true in case of an error.
27 void OnSyncHandleReady(bool* signal, bool* error, MojoResult result) {
28 *signal = true;
29 *error = result != MOJO_RESULT_OK;
30 }
31
32 } // namespace
33
34 bool SyncMessageFilter::Send(Message* message) { 18 bool SyncMessageFilter::Send(Message* message) {
35 if (!message->is_sync()) { 19 if (!message->is_sync()) {
36 { 20 {
37 base::AutoLock auto_lock(lock_); 21 base::AutoLock auto_lock(lock_);
38 if (sender_ && is_channel_send_thread_safe_) { 22 if (sender_ && is_channel_send_thread_safe_) {
39 sender_->Send(message); 23 sender_->Send(message);
40 return true; 24 return true;
41 } else if (!io_task_runner_.get()) { 25 } else if (!io_task_runner_.get()) {
42 pending_messages_.emplace_back(base::WrapUnique(message)); 26 pending_messages_.push_back(message);
43 return true; 27 return true;
44 } 28 }
45 } 29 }
46 io_task_runner_->PostTask( 30 io_task_runner_->PostTask(
47 FROM_HERE, 31 FROM_HERE,
48 base::Bind(&SyncMessageFilter::SendOnIOThread, this, message)); 32 base::Bind(&SyncMessageFilter::SendOnIOThread, this, message));
49 return true; 33 return true;
50 } 34 }
51 35
52 MojoEvent done_event; 36 base::WaitableEvent done_event(
37 base::WaitableEvent::ResetPolicy::MANUAL,
38 base::WaitableEvent::InitialState::NOT_SIGNALED);
53 PendingSyncMsg pending_message( 39 PendingSyncMsg pending_message(
54 SyncMessage::GetMessageId(*message), 40 SyncMessage::GetMessageId(*message),
55 static_cast<SyncMessage*>(message)->GetReplyDeserializer(), 41 static_cast<SyncMessage*>(message)->GetReplyDeserializer(),
56 &done_event); 42 &done_event);
57 43
58 { 44 {
59 base::AutoLock auto_lock(lock_); 45 base::AutoLock auto_lock(lock_);
60 // Can't use this class on the main thread or else it can lead to deadlocks. 46 // Can't use this class on the main thread or else it can lead to deadlocks.
61 // Also by definition, can't use this on IO thread since we're blocking it. 47 // Also by definition, can't use this on IO thread since we're blocking it.
62 if (base::ThreadTaskRunnerHandle::IsSet()) { 48 if (base::ThreadTaskRunnerHandle::IsSet()) {
63 DCHECK(base::ThreadTaskRunnerHandle::Get() != listener_task_runner_); 49 DCHECK(base::ThreadTaskRunnerHandle::Get() != listener_task_runner_);
64 DCHECK(base::ThreadTaskRunnerHandle::Get() != io_task_runner_); 50 DCHECK(base::ThreadTaskRunnerHandle::Get() != io_task_runner_);
65 } 51 }
66 pending_sync_messages_.insert(&pending_message); 52 pending_sync_messages_.insert(&pending_message);
67 53
68 if (io_task_runner_.get()) { 54 if (io_task_runner_.get()) {
69 io_task_runner_->PostTask( 55 io_task_runner_->PostTask(
70 FROM_HERE, 56 FROM_HERE,
71 base::Bind(&SyncMessageFilter::SendOnIOThread, this, message)); 57 base::Bind(&SyncMessageFilter::SendOnIOThread, this, message));
72 } else { 58 } else {
73 pending_messages_.emplace_back(base::WrapUnique(message)); 59 pending_messages_.push_back(message);
74 } 60 }
75 } 61 }
76 62
77 bool done = false; 63 base::WaitableEvent* events[2] = { shutdown_event_, &done_event };
78 bool shutdown = false; 64 if (base::WaitableEvent::WaitMany(events, 2) == 1) {
79 bool error = false;
80 scoped_refptr<mojo::SyncHandleRegistry> registry =
81 mojo::SyncHandleRegistry::current();
82 registry->RegisterHandle(shutdown_mojo_event_.GetHandle(),
83 MOJO_HANDLE_SIGNAL_READABLE,
84 base::Bind(&OnSyncHandleReady, &shutdown, &error));
85 registry->RegisterHandle(done_event.GetHandle(),
86 MOJO_HANDLE_SIGNAL_READABLE,
87 base::Bind(&OnSyncHandleReady, &done, &error));
88
89 const bool* stop_flags[] = { &done, &shutdown };
90 bool result = registry->WatchAllHandles(stop_flags, 2);
91 DCHECK(result);
92 DCHECK(!error);
93
94 if (done) {
95 TRACE_EVENT_FLOW_END0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), 65 TRACE_EVENT_FLOW_END0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
96 "SyncMessageFilter::Send", &done_event); 66 "SyncMessageFilter::Send", &done_event);
97 } 67 }
98 registry->UnregisterHandle(shutdown_mojo_event_.GetHandle());
99 registry->UnregisterHandle(done_event.GetHandle());
100 68
101 { 69 {
102 base::AutoLock auto_lock(lock_); 70 base::AutoLock auto_lock(lock_);
103 delete pending_message.deserializer; 71 delete pending_message.deserializer;
104 pending_sync_messages_.erase(&pending_message); 72 pending_sync_messages_.erase(&pending_message);
105 } 73 }
106 74
107 return pending_message.send_result; 75 return pending_message.send_result;
108 } 76 }
109 77
110 void SyncMessageFilter::OnFilterAdded(Sender* sender) { 78 void SyncMessageFilter::OnFilterAdded(Sender* sender) {
111 std::vector<std::unique_ptr<Message>> pending_messages; 79 std::vector<Message*> pending_messages;
112 { 80 {
113 base::AutoLock auto_lock(lock_); 81 base::AutoLock auto_lock(lock_);
114 sender_ = sender; 82 sender_ = sender;
115 io_task_runner_ = base::ThreadTaskRunnerHandle::Get(); 83 io_task_runner_ = base::ThreadTaskRunnerHandle::Get();
116 shutdown_watcher_.StartWatching( 84 pending_messages_.release(&pending_messages);
117 shutdown_event_,
118 base::Bind(&SyncMessageFilter::OnShutdownEventSignaled, this));
119 std::swap(pending_messages_, pending_messages);
120 } 85 }
121 for (auto& msg : pending_messages) 86 for (auto* msg : pending_messages)
122 SendOnIOThread(msg.release()); 87 SendOnIOThread(msg);
123 } 88 }
124 89
125 void SyncMessageFilter::OnChannelError() { 90 void SyncMessageFilter::OnChannelError() {
126 base::AutoLock auto_lock(lock_); 91 base::AutoLock auto_lock(lock_);
127 sender_ = NULL; 92 sender_ = NULL;
128 shutdown_watcher_.StopWatching();
129 SignalAllEvents(); 93 SignalAllEvents();
130 } 94 }
131 95
132 void SyncMessageFilter::OnChannelClosing() { 96 void SyncMessageFilter::OnChannelClosing() {
133 base::AutoLock auto_lock(lock_); 97 base::AutoLock auto_lock(lock_);
134 sender_ = NULL; 98 sender_ = NULL;
135 shutdown_watcher_.StopWatching();
136 SignalAllEvents(); 99 SignalAllEvents();
137 } 100 }
138 101
139 bool SyncMessageFilter::OnMessageReceived(const Message& message) { 102 bool SyncMessageFilter::OnMessageReceived(const Message& message) {
140 base::AutoLock auto_lock(lock_); 103 base::AutoLock auto_lock(lock_);
141 for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin(); 104 for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin();
142 iter != pending_sync_messages_.end(); ++iter) { 105 iter != pending_sync_messages_.end(); ++iter) {
143 if (SyncMessage::IsMessageReplyTo(message, (*iter)->id)) { 106 if (SyncMessage::IsMessageReplyTo(message, (*iter)->id)) {
144 if (!message.is_reply_error()) { 107 if (!message.is_reply_error()) {
145 (*iter)->send_result = 108 (*iter)->send_result =
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 lock_.AssertAcquired(); 150 lock_.AssertAcquired();
188 for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin(); 151 for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin();
189 iter != pending_sync_messages_.end(); ++iter) { 152 iter != pending_sync_messages_.end(); ++iter) {
190 TRACE_EVENT_FLOW_BEGIN0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), 153 TRACE_EVENT_FLOW_BEGIN0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
191 "SyncMessageFilter::SignalAllEvents", 154 "SyncMessageFilter::SignalAllEvents",
192 (*iter)->done_event); 155 (*iter)->done_event);
193 (*iter)->done_event->Signal(); 156 (*iter)->done_event->Signal();
194 } 157 }
195 } 158 }
196 159
197 void SyncMessageFilter::OnShutdownEventSignaled(base::WaitableEvent* event) {
198 DCHECK_EQ(event, shutdown_event_);
199 shutdown_mojo_event_.Signal();
200 }
201
202 } // namespace IPC 160 } // 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