| 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 |