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