| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "mojo/edk/system/raw_channel.h" | 5 #include "mojo/edk/system/raw_channel.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <sys/uio.h> | 8 #include <sys/uio.h> |
| 9 #include <unistd.h> | 9 #include <unistd.h> |
| 10 | 10 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 platform_handles->size() > embedder::kPlatformChannelMaxNumHandles) { | 128 platform_handles->size() > embedder::kPlatformChannelMaxNumHandles) { |
| 129 // We can't attach all the FDs to a single message, so we have to "split" | 129 // We can't attach all the FDs to a single message, so we have to "split" |
| 130 // the message. Send as many control messages as needed first with FDs | 130 // the message. Send as many control messages as needed first with FDs |
| 131 // attached (and no data). | 131 // attached (and no data). |
| 132 size_t i = 0; | 132 size_t i = 0; |
| 133 for (; platform_handles->size() - i > | 133 for (; platform_handles->size() - i > |
| 134 embedder::kPlatformChannelMaxNumHandles; | 134 embedder::kPlatformChannelMaxNumHandles; |
| 135 i += embedder::kPlatformChannelMaxNumHandles) { | 135 i += embedder::kPlatformChannelMaxNumHandles) { |
| 136 scoped_ptr<MessageInTransit> fd_message(new MessageInTransit( | 136 scoped_ptr<MessageInTransit> fd_message(new MessageInTransit( |
| 137 MessageInTransit::kTypeRawChannel, | 137 MessageInTransit::kTypeRawChannel, |
| 138 MessageInTransit::kSubtypeRawChannelPosixExtraPlatformHandles, | 138 MessageInTransit::kSubtypeRawChannelPosixExtraPlatformHandles, 0, |
| 139 0, | |
| 140 nullptr)); | 139 nullptr)); |
| 141 embedder::ScopedPlatformHandleVectorPtr fds( | 140 embedder::ScopedPlatformHandleVectorPtr fds( |
| 142 new embedder::PlatformHandleVector( | 141 new embedder::PlatformHandleVector( |
| 143 platform_handles->begin() + i, | 142 platform_handles->begin() + i, |
| 144 platform_handles->begin() + i + | 143 platform_handles->begin() + i + |
| 145 embedder::kPlatformChannelMaxNumHandles)); | 144 embedder::kPlatformChannelMaxNumHandles)); |
| 146 fd_message->SetTransportData( | 145 fd_message->SetTransportData( |
| 147 make_scoped_ptr(new TransportData(fds.Pass()))); | 146 make_scoped_ptr(new TransportData(fds.Pass()))); |
| 148 RawChannel::EnqueueMessageNoLock(fd_message.Pass()); | 147 RawChannel::EnqueueMessageNoLock(fd_message.Pass()); |
| 149 } | 148 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 write_result = embedder::PlatformChannelSendmsgWithHandles( | 245 write_result = embedder::PlatformChannelSendmsgWithHandles( |
| 247 fd_.get(), iov, buffer_count, platform_handles, num_platform_handles); | 246 fd_.get(), iov, buffer_count, platform_handles, num_platform_handles); |
| 248 for (size_t i = 0; i < num_platform_handles; i++) | 247 for (size_t i = 0; i < num_platform_handles; i++) |
| 249 platform_handles[i].CloseIfNecessary(); | 248 platform_handles[i].CloseIfNecessary(); |
| 250 } else { | 249 } else { |
| 251 std::vector<WriteBuffer::Buffer> buffers; | 250 std::vector<WriteBuffer::Buffer> buffers; |
| 252 write_buffer_no_lock()->GetBuffers(&buffers); | 251 write_buffer_no_lock()->GetBuffers(&buffers); |
| 253 DCHECK(!buffers.empty()); | 252 DCHECK(!buffers.empty()); |
| 254 | 253 |
| 255 if (buffers.size() == 1) { | 254 if (buffers.size() == 1) { |
| 256 write_result = embedder::PlatformChannelWrite( | 255 write_result = embedder::PlatformChannelWrite(fd_.get(), buffers[0].addr, |
| 257 fd_.get(), buffers[0].addr, buffers[0].size); | 256 buffers[0].size); |
| 258 } else { | 257 } else { |
| 259 const size_t kMaxBufferCount = 10; | 258 const size_t kMaxBufferCount = 10; |
| 260 iovec iov[kMaxBufferCount]; | 259 iovec iov[kMaxBufferCount]; |
| 261 size_t buffer_count = std::min(buffers.size(), kMaxBufferCount); | 260 size_t buffer_count = std::min(buffers.size(), kMaxBufferCount); |
| 262 for (size_t i = 0; i < buffer_count; ++i) { | 261 for (size_t i = 0; i < buffer_count; ++i) { |
| 263 iov[i].iov_base = const_cast<char*>(buffers[i].addr); | 262 iov[i].iov_base = const_cast<char*>(buffers[i].addr); |
| 264 iov[i].iov_len = buffers[i].size; | 263 iov[i].iov_len = buffers[i].size; |
| 265 } | 264 } |
| 266 | 265 |
| 267 write_result = | 266 write_result = |
| (...skipping 27 matching lines...) Expand all Loading... |
| 295 // If we're not on the I/O thread, we have to post a task to do this. | 294 // If we're not on the I/O thread, we have to post a task to do this. |
| 296 if (base::MessageLoop::current() != message_loop_for_io()) { | 295 if (base::MessageLoop::current() != message_loop_for_io()) { |
| 297 message_loop_for_io()->PostTask(FROM_HERE, | 296 message_loop_for_io()->PostTask(FROM_HERE, |
| 298 base::Bind(&RawChannelPosix::WaitToWrite, | 297 base::Bind(&RawChannelPosix::WaitToWrite, |
| 299 weak_ptr_factory_.GetWeakPtr())); | 298 weak_ptr_factory_.GetWeakPtr())); |
| 300 pending_write_ = true; | 299 pending_write_ = true; |
| 301 return IO_PENDING; | 300 return IO_PENDING; |
| 302 } | 301 } |
| 303 | 302 |
| 304 if (message_loop_for_io()->WatchFileDescriptor( | 303 if (message_loop_for_io()->WatchFileDescriptor( |
| 305 fd_.get().fd, | 304 fd_.get().fd, false, base::MessageLoopForIO::WATCH_WRITE, |
| 306 false, | 305 write_watcher_.get(), this)) { |
| 307 base::MessageLoopForIO::WATCH_WRITE, | |
| 308 write_watcher_.get(), | |
| 309 this)) { | |
| 310 pending_write_ = true; | 306 pending_write_ = true; |
| 311 return IO_PENDING; | 307 return IO_PENDING; |
| 312 } | 308 } |
| 313 | 309 |
| 314 return IO_FAILED_UNKNOWN; | 310 return IO_FAILED_UNKNOWN; |
| 315 } | 311 } |
| 316 | 312 |
| 317 bool RawChannelPosix::OnInit() { | 313 bool RawChannelPosix::OnInit() { |
| 318 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); | 314 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); |
| 319 | 315 |
| 320 DCHECK(!read_watcher_); | 316 DCHECK(!read_watcher_); |
| 321 read_watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher()); | 317 read_watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher()); |
| 322 DCHECK(!write_watcher_); | 318 DCHECK(!write_watcher_); |
| 323 write_watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher()); | 319 write_watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher()); |
| 324 | 320 |
| 325 if (!message_loop_for_io()->WatchFileDescriptor( | 321 if (!message_loop_for_io()->WatchFileDescriptor( |
| 326 fd_.get().fd, | 322 fd_.get().fd, true, base::MessageLoopForIO::WATCH_READ, |
| 327 true, | 323 read_watcher_.get(), this)) { |
| 328 base::MessageLoopForIO::WATCH_READ, | |
| 329 read_watcher_.get(), | |
| 330 this)) { | |
| 331 // TODO(vtl): I'm not sure |WatchFileDescriptor()| actually fails cleanly | 324 // TODO(vtl): I'm not sure |WatchFileDescriptor()| actually fails cleanly |
| 332 // (in the sense of returning the message loop's state to what it was before | 325 // (in the sense of returning the message loop's state to what it was before |
| 333 // it was called). | 326 // it was called). |
| 334 read_watcher_.reset(); | 327 read_watcher_.reset(); |
| 335 write_watcher_.reset(); | 328 write_watcher_.reset(); |
| 336 return false; | 329 return false; |
| 337 } | 330 } |
| 338 | 331 |
| 339 return true; | 332 return true; |
| 340 } | 333 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 if (read_platform_handles_.size() > old_num_platform_handles) { | 407 if (read_platform_handles_.size() > old_num_platform_handles) { |
| 415 DCHECK_LE(read_platform_handles_.size() - old_num_platform_handles, | 408 DCHECK_LE(read_platform_handles_.size() - old_num_platform_handles, |
| 416 embedder::kPlatformChannelMaxNumHandles); | 409 embedder::kPlatformChannelMaxNumHandles); |
| 417 | 410 |
| 418 // We should never accumulate more than |TransportData::kMaxPlatformHandles | 411 // We should never accumulate more than |TransportData::kMaxPlatformHandles |
| 419 // + embedder::kPlatformChannelMaxNumHandles| handles. (The latter part is | 412 // + embedder::kPlatformChannelMaxNumHandles| handles. (The latter part is |
| 420 // possible because we could have accumulated all the handles for a message, | 413 // possible because we could have accumulated all the handles for a message, |
| 421 // then received the message data plus the first set of handles for the next | 414 // then received the message data plus the first set of handles for the next |
| 422 // message in the subsequent |recvmsg()|.) | 415 // message in the subsequent |recvmsg()|.) |
| 423 if (read_platform_handles_.size() > | 416 if (read_platform_handles_.size() > |
| 424 (TransportData::kMaxPlatformHandles + | 417 (TransportData::GetMaxPlatformHandles() + |
| 425 embedder::kPlatformChannelMaxNumHandles)) { | 418 embedder::kPlatformChannelMaxNumHandles)) { |
| 426 LOG(ERROR) << "Received too many platform handles"; | 419 LOG(ERROR) << "Received too many platform handles"; |
| 427 embedder::CloseAllPlatformHandles(&read_platform_handles_); | 420 embedder::CloseAllPlatformHandles(&read_platform_handles_); |
| 428 read_platform_handles_.clear(); | 421 read_platform_handles_.clear(); |
| 429 return IO_FAILED_UNKNOWN; | 422 return IO_FAILED_UNKNOWN; |
| 430 } | 423 } |
| 431 } | 424 } |
| 432 | 425 |
| 433 if (read_result > 0) { | 426 if (read_result > 0) { |
| 434 *bytes_read = static_cast<size_t>(read_result); | 427 *bytes_read = static_cast<size_t>(read_result); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 448 PLOG(WARNING) << "recvmsg"; | 441 PLOG(WARNING) << "recvmsg"; |
| 449 return IO_FAILED_UNKNOWN; | 442 return IO_FAILED_UNKNOWN; |
| 450 } | 443 } |
| 451 | 444 |
| 452 void RawChannelPosix::WaitToWrite() { | 445 void RawChannelPosix::WaitToWrite() { |
| 453 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); | 446 DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io()); |
| 454 | 447 |
| 455 DCHECK(write_watcher_); | 448 DCHECK(write_watcher_); |
| 456 | 449 |
| 457 if (!message_loop_for_io()->WatchFileDescriptor( | 450 if (!message_loop_for_io()->WatchFileDescriptor( |
| 458 fd_.get().fd, | 451 fd_.get().fd, false, base::MessageLoopForIO::WATCH_WRITE, |
| 459 false, | 452 write_watcher_.get(), this)) { |
| 460 base::MessageLoopForIO::WATCH_WRITE, | |
| 461 write_watcher_.get(), | |
| 462 this)) { | |
| 463 { | 453 { |
| 464 base::AutoLock locker(write_lock()); | 454 base::AutoLock locker(write_lock()); |
| 465 | 455 |
| 466 DCHECK(pending_write_); | 456 DCHECK(pending_write_); |
| 467 pending_write_ = false; | 457 pending_write_ = false; |
| 468 } | 458 } |
| 469 OnWriteCompleted(IO_FAILED_UNKNOWN, 0, 0); | 459 OnWriteCompleted(IO_FAILED_UNKNOWN, 0, 0); |
| 470 } | 460 } |
| 471 } | 461 } |
| 472 | 462 |
| 473 } // namespace | 463 } // namespace |
| 474 | 464 |
| 475 // ----------------------------------------------------------------------------- | 465 // ----------------------------------------------------------------------------- |
| 476 | 466 |
| 477 // Static factory method declared in raw_channel.h. | 467 // Static factory method declared in raw_channel.h. |
| 478 // static | 468 // static |
| 479 scoped_ptr<RawChannel> RawChannel::Create( | 469 scoped_ptr<RawChannel> RawChannel::Create( |
| 480 embedder::ScopedPlatformHandle handle) { | 470 embedder::ScopedPlatformHandle handle) { |
| 481 return make_scoped_ptr(new RawChannelPosix(handle.Pass())); | 471 return make_scoped_ptr(new RawChannelPosix(handle.Pass())); |
| 482 } | 472 } |
| 483 | 473 |
| 484 } // namespace system | 474 } // namespace system |
| 485 } // namespace mojo | 475 } // namespace mojo |
| OLD | NEW |