| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/channel.h" | 5 #include "mojo/edk/system/channel.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <sys/uio.h> | 8 #include <sys/uio.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 59 |
| 60 size_t data_offset() const { return offset_; } | 60 size_t data_offset() const { return offset_; } |
| 61 void advance_data_offset(size_t num_bytes) { | 61 void advance_data_offset(size_t num_bytes) { |
| 62 DCHECK_GT(message_->data_num_bytes(), offset_ + num_bytes); | 62 DCHECK_GT(message_->data_num_bytes(), offset_ + num_bytes); |
| 63 offset_ += num_bytes; | 63 offset_ += num_bytes; |
| 64 } | 64 } |
| 65 | 65 |
| 66 ScopedPlatformHandleVectorPtr TakeHandles() { return std::move(handles_); } | 66 ScopedPlatformHandleVectorPtr TakeHandles() { return std::move(handles_); } |
| 67 Channel::MessagePtr TakeMessage() { return std::move(message_); } | 67 Channel::MessagePtr TakeMessage() { return std::move(message_); } |
| 68 | 68 |
| 69 void SetHandles(ScopedPlatformHandleVectorPtr handles) { |
| 70 handles_ = std::move(handles); |
| 71 } |
| 72 |
| 69 private: | 73 private: |
| 70 Channel::MessagePtr message_; | 74 Channel::MessagePtr message_; |
| 71 size_t offset_; | 75 size_t offset_; |
| 72 ScopedPlatformHandleVectorPtr handles_; | 76 ScopedPlatformHandleVectorPtr handles_; |
| 73 | 77 |
| 74 DISALLOW_COPY_AND_ASSIGN(MessageView); | 78 DISALLOW_COPY_AND_ASSIGN(MessageView); |
| 75 }; | 79 }; |
| 76 | 80 |
| 77 class ChannelPosix : public Channel, | 81 class ChannelPosix : public Channel, |
| 78 public base::MessageLoop::DestructionObserver, | 82 public base::MessageLoop::DestructionObserver, |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 ssize_t result; | 274 ssize_t result; |
| 271 ScopedPlatformHandleVectorPtr handles = message_view.TakeHandles(); | 275 ScopedPlatformHandleVectorPtr handles = message_view.TakeHandles(); |
| 272 if (handles && handles->size()) { | 276 if (handles && handles->size()) { |
| 273 iovec iov = { | 277 iovec iov = { |
| 274 const_cast<void*>(message_view.data()), | 278 const_cast<void*>(message_view.data()), |
| 275 message_view.data_num_bytes() | 279 message_view.data_num_bytes() |
| 276 }; | 280 }; |
| 277 // TODO: Handle lots of handles. | 281 // TODO: Handle lots of handles. |
| 278 result = PlatformChannelSendmsgWithHandles( | 282 result = PlatformChannelSendmsgWithHandles( |
| 279 handle_.get(), &iov, 1, handles->data(), handles->size()); | 283 handle_.get(), &iov, 1, handles->data(), handles->size()); |
| 284 if (result >= 0) { |
| 280 #if defined(OS_MACOSX) | 285 #if defined(OS_MACOSX) |
| 281 // There is a bug on OSX which makes it dangerous to close | 286 // There is a bug on OSX which makes it dangerous to close |
| 282 // a file descriptor while it is in transit. So instead we | 287 // a file descriptor while it is in transit. So instead we |
| 283 // store the file descriptor in a set and send a message to | 288 // store the file descriptor in a set and send a message to |
| 284 // the recipient, which is queued AFTER the message that | 289 // the recipient, which is queued AFTER the message that |
| 285 // sent the FD. The recipient will reply to the message, | 290 // sent the FD. The recipient will reply to the message, |
| 286 // letting us know that it is now safe to close the file | 291 // letting us know that it is now safe to close the file |
| 287 // descriptor. For more information, see: | 292 // descriptor. For more information, see: |
| 288 // http://crbug.com/298276 | 293 // http://crbug.com/298276 |
| 289 std::vector<int> fds; | 294 std::vector<int> fds; |
| 290 for (auto& handle : *handles) | |
| 291 fds.push_back(handle.handle); | |
| 292 { | |
| 293 base::AutoLock l(handles_to_close_lock_); | |
| 294 for (auto& handle : *handles) | 295 for (auto& handle : *handles) |
| 295 handles_to_close_->push_back(handle); | 296 fds.push_back(handle.handle); |
| 297 { |
| 298 base::AutoLock l(handles_to_close_lock_); |
| 299 for (auto& handle : *handles) |
| 300 handles_to_close_->push_back(handle); |
| 301 } |
| 302 MessagePtr fds_message( |
| 303 new Channel::Message(sizeof(fds[0]) * fds.size(), 0, |
| 304 Message::Header::MessageType::HANDLES_SENT)); |
| 305 memcpy(fds_message->mutable_payload(), fds.data(), |
| 306 sizeof(fds[0]) * fds.size()); |
| 307 outgoing_messages_.emplace_back(std::move(fds_message), 0); |
| 308 handles->clear(); |
| 309 #else |
| 310 handles.reset(); |
| 311 #endif // defined(OS_MACOSX) |
| 296 } | 312 } |
| 297 MessagePtr fds_message( | |
| 298 new Channel::Message(sizeof(fds[0]) * fds.size(), 0, | |
| 299 Message::Header::MessageType::HANDLES_SENT)); | |
| 300 memcpy(fds_message->mutable_payload(), fds.data(), | |
| 301 sizeof(fds[0]) * fds.size()); | |
| 302 outgoing_messages_.emplace_back(std::move(fds_message), 0); | |
| 303 handles->clear(); | |
| 304 #else | |
| 305 handles.reset(); | |
| 306 #endif // defined(OS_MACOSX) | |
| 307 } else { | 313 } else { |
| 308 result = PlatformChannelWrite(handle_.get(), message_view.data(), | 314 result = PlatformChannelWrite(handle_.get(), message_view.data(), |
| 309 message_view.data_num_bytes()); | 315 message_view.data_num_bytes()); |
| 310 } | 316 } |
| 311 | 317 |
| 312 if (result < 0) { | 318 if (result < 0) { |
| 313 if (errno != EAGAIN && errno != EWOULDBLOCK) | 319 if (errno != EAGAIN && errno != EWOULDBLOCK) |
| 314 return false; | 320 return false; |
| 321 message_view.SetHandles(std::move(handles)); |
| 315 outgoing_messages_.emplace_front(std::move(message_view)); | 322 outgoing_messages_.emplace_front(std::move(message_view)); |
| 316 WaitForWriteOnIOThreadNoLock(); | 323 WaitForWriteOnIOThreadNoLock(); |
| 317 return true; | 324 return true; |
| 318 } | 325 } |
| 319 | 326 |
| 320 bytes_written = static_cast<size_t>(result); | 327 bytes_written = static_cast<size_t>(result); |
| 321 } while (bytes_written < message_view.data_num_bytes()); | 328 } while (bytes_written < message_view.data_num_bytes()); |
| 322 | 329 |
| 323 return FlushOutgoingMessagesNoLock(); | 330 return FlushOutgoingMessagesNoLock(); |
| 324 } | 331 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 // static | 448 // static |
| 442 scoped_refptr<Channel> Channel::Create( | 449 scoped_refptr<Channel> Channel::Create( |
| 443 Delegate* delegate, | 450 Delegate* delegate, |
| 444 ScopedPlatformHandle platform_handle, | 451 ScopedPlatformHandle platform_handle, |
| 445 scoped_refptr<base::TaskRunner> io_task_runner) { | 452 scoped_refptr<base::TaskRunner> io_task_runner) { |
| 446 return new ChannelPosix(delegate, std::move(platform_handle), io_task_runner); | 453 return new ChannelPosix(delegate, std::move(platform_handle), io_task_runner); |
| 447 } | 454 } |
| 448 | 455 |
| 449 } // namespace edk | 456 } // namespace edk |
| 450 } // namespace mojo | 457 } // namespace mojo |
| OLD | NEW |