OLD | NEW |
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_channel_nacl.h" | 5 #include "ipc/ipc_channel_nacl.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <sys/types.h> | 9 #include <sys/types.h> |
10 | 10 |
11 #include <algorithm> | 11 #include <algorithm> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
16 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
17 #include "base/task_runner_util.h" | 17 #include "base/task_runner_util.h" |
18 #include "base/threading/simple_thread.h" | 18 #include "base/threading/simple_thread.h" |
19 #include "ipc/file_descriptor_set_posix.h" | 19 #include "ipc/file_descriptor_set_posix.h" |
20 #include "ipc/ipc_listener.h" | |
21 #include "ipc/ipc_logging.h" | 20 #include "ipc/ipc_logging.h" |
22 #include "native_client/src/public/imc_syscalls.h" | 21 #include "native_client/src/public/imc_syscalls.h" |
23 #include "native_client/src/public/imc_types.h" | 22 #include "native_client/src/public/imc_types.h" |
24 | 23 |
25 namespace IPC { | 24 namespace IPC { |
26 | 25 |
27 struct MessageContents { | 26 struct MessageContents { |
28 std::vector<char> data; | 27 std::vector<char> data; |
29 std::vector<int> fds; | 28 std::vector<int> fds; |
30 }; | 29 }; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; | 131 const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; |
133 LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name | 132 LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name |
134 << "\" in " << modestr << " mode"; | 133 << "\" in " << modestr << " mode"; |
135 } | 134 } |
136 } | 135 } |
137 | 136 |
138 Channel::ChannelImpl::~ChannelImpl() { | 137 Channel::ChannelImpl::~ChannelImpl() { |
139 Close(); | 138 Close(); |
140 } | 139 } |
141 | 140 |
142 base::ProcessId Channel::ChannelImpl::peer_pid() const { | |
143 // This shouldn't actually get used in the untrusted side of the proxy, and we | |
144 // don't have the real pid anyway. | |
145 return -1; | |
146 } | |
147 | |
148 bool Channel::ChannelImpl::Connect() { | 141 bool Channel::ChannelImpl::Connect() { |
149 if (pipe_ == -1) { | 142 if (pipe_ == -1) { |
150 DLOG(WARNING) << "Channel creation failed: " << pipe_name_; | 143 DLOG(INFO) << "Channel creation failed: " << pipe_name_; |
151 return false; | 144 return false; |
152 } | 145 } |
153 | 146 |
154 // Note that Connect is called on the "Channel" thread (i.e., the same thread | 147 // Note that Connect is called on the "Channel" thread (i.e., the same thread |
155 // where Channel::Send will be called, and the same thread that should receive | 148 // where Channel::Send will be called, and the same thread that should receive |
156 // messages). The constructor might be invoked on another thread (see | 149 // messages). The constructor might be invoked on another thread (see |
157 // ChannelProxy for an example of that). Therefore, we must wait until Connect | 150 // ChannelProxy for an example of that). Therefore, we must wait until Connect |
158 // is called to decide which MessageLoopProxy to pass to ReaderThreadRunner. | 151 // is called to decide which MessageLoopProxy to pass to ReaderThreadRunner. |
159 reader_thread_runner_.reset( | 152 reader_thread_runner_.reset( |
160 new ReaderThreadRunner( | 153 new ReaderThreadRunner( |
161 pipe_, | 154 pipe_, |
162 base::Bind(&Channel::ChannelImpl::DidRecvMsg, | 155 base::Bind(&Channel::ChannelImpl::DidRecvMsg, |
163 weak_ptr_factory_.GetWeakPtr()), | 156 weak_ptr_factory_.GetWeakPtr()), |
164 base::Bind(&Channel::ChannelImpl::ReadDidFail, | 157 base::Bind(&Channel::ChannelImpl::ReadDidFail, |
165 weak_ptr_factory_.GetWeakPtr()), | 158 weak_ptr_factory_.GetWeakPtr()), |
166 base::MessageLoopProxy::current())); | 159 base::MessageLoopProxy::current())); |
167 reader_thread_.reset( | 160 reader_thread_.reset( |
168 new base::DelegateSimpleThread(reader_thread_runner_.get(), | 161 new base::DelegateSimpleThread(reader_thread_runner_.get(), |
169 "ipc_channel_nacl reader thread")); | 162 "ipc_channel_nacl reader thread")); |
170 reader_thread_->Start(); | 163 reader_thread_->Start(); |
171 waiting_connect_ = false; | 164 waiting_connect_ = false; |
172 // If there were any messages queued before connection, send them. | 165 // If there were any messages queued before connection, send them. |
173 ProcessOutgoingMessages(); | 166 ProcessOutgoingMessages(); |
174 base::MessageLoopProxy::current()->PostTask(FROM_HERE, | |
175 base::Bind(&Channel::ChannelImpl::CallOnChannelConnected, | |
176 weak_ptr_factory_.GetWeakPtr())); | |
177 | |
178 return true; | 167 return true; |
179 } | 168 } |
180 | 169 |
181 void Channel::ChannelImpl::Close() { | 170 void Channel::ChannelImpl::Close() { |
182 // For now, we assume that at shutdown, the reader thread will be woken with | 171 // For now, we assume that at shutdown, the reader thread will be woken with |
183 // a failure (see NaClIPCAdapter::BlockingRead and CloseChannel). Or... we | 172 // a failure (see NaClIPCAdapter::BlockingRead and CloseChannel). Or... we |
184 // might simply be killed with no chance to clean up anyway :-). | 173 // might simply be killed with no chance to clean up anyway :-). |
185 // If untrusted code tries to close the channel prior to shutdown, it's likely | 174 // If untrusted code tries to close the channel prior to shutdown, it's likely |
186 // to hang. | 175 // to hang. |
187 // TODO(dmichael): Can we do anything smarter here to make sure the reader | 176 // TODO(dmichael): Can we do anything smarter here to make sure the reader |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 msg->file_descriptor_set()->CommitAll(); | 286 msg->file_descriptor_set()->CommitAll(); |
298 } | 287 } |
299 | 288 |
300 // Message sent OK! | 289 // Message sent OK! |
301 DVLOG(2) << "sent message @" << msg.get() << " with type " << msg->type() | 290 DVLOG(2) << "sent message @" << msg.get() << " with type " << msg->type() |
302 << " on fd " << pipe_; | 291 << " on fd " << pipe_; |
303 } | 292 } |
304 return true; | 293 return true; |
305 } | 294 } |
306 | 295 |
307 void Channel::ChannelImpl::CallOnChannelConnected() { | |
308 listener()->OnChannelConnected(peer_pid()); | |
309 } | |
310 | |
311 Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData( | 296 Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData( |
312 char* buffer, | 297 char* buffer, |
313 int buffer_len, | 298 int buffer_len, |
314 int* bytes_read) { | 299 int* bytes_read) { |
315 *bytes_read = 0; | 300 *bytes_read = 0; |
316 if (pipe_ == -1) | 301 if (pipe_ == -1) |
317 return READ_FAILED; | 302 return READ_FAILED; |
318 if (read_queue_.empty()) | 303 if (read_queue_.empty()) |
319 return READ_PENDING; | 304 return READ_PENDING; |
320 while (!read_queue_.empty() && *bytes_read < buffer_len) { | 305 while (!read_queue_.empty() && *bytes_read < buffer_len) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 | 365 |
381 bool Channel::Connect() { | 366 bool Channel::Connect() { |
382 return channel_impl_->Connect(); | 367 return channel_impl_->Connect(); |
383 } | 368 } |
384 | 369 |
385 void Channel::Close() { | 370 void Channel::Close() { |
386 channel_impl_->Close(); | 371 channel_impl_->Close(); |
387 } | 372 } |
388 | 373 |
389 base::ProcessId Channel::peer_pid() const { | 374 base::ProcessId Channel::peer_pid() const { |
390 return channel_impl_->peer_pid(); | 375 // This shouldn't actually get used in the untrusted side of the proxy, and we |
| 376 // don't have the real pid anyway. |
| 377 return -1; |
391 } | 378 } |
392 | 379 |
393 bool Channel::Send(Message* message) { | 380 bool Channel::Send(Message* message) { |
394 return channel_impl_->Send(message); | 381 return channel_impl_->Send(message); |
395 } | 382 } |
396 | 383 |
397 } // namespace IPC | 384 } // namespace IPC |
OLD | NEW |