Index: mojo/edk/system/channel_posix.cc |
diff --git a/mojo/edk/system/channel_posix.cc b/mojo/edk/system/channel_posix.cc |
index d09c0bc5dd573867ec1ca43b42d98ae2cf895e39..8edafd9477003f48095b8b7396ab0701bf10ca52 100644 |
--- a/mojo/edk/system/channel_posix.cc |
+++ b/mojo/edk/system/channel_posix.cc |
@@ -66,6 +66,10 @@ class MessageView { |
ScopedPlatformHandleVectorPtr TakeHandles() { return std::move(handles_); } |
Channel::MessagePtr TakeMessage() { return std::move(message_); } |
+ void SetHandles(ScopedPlatformHandleVectorPtr handles) { |
+ handles_ = std::move(handles); |
+ } |
+ |
private: |
Channel::MessagePtr message_; |
size_t offset_; |
@@ -277,33 +281,35 @@ class ChannelPosix : public Channel, |
// TODO: Handle lots of handles. |
result = PlatformChannelSendmsgWithHandles( |
handle_.get(), &iov, 1, handles->data(), handles->size()); |
+ if (result >= 0) { |
#if defined(OS_MACOSX) |
- // There is a bug on OSX which makes it dangerous to close |
- // a file descriptor while it is in transit. So instead we |
- // store the file descriptor in a set and send a message to |
- // the recipient, which is queued AFTER the message that |
- // sent the FD. The recipient will reply to the message, |
- // letting us know that it is now safe to close the file |
- // descriptor. For more information, see: |
- // http://crbug.com/298276 |
- std::vector<int> fds; |
- for (auto& handle : *handles) |
- fds.push_back(handle.handle); |
- { |
- base::AutoLock l(handles_to_close_lock_); |
+ // There is a bug on OSX which makes it dangerous to close |
+ // a file descriptor while it is in transit. So instead we |
+ // store the file descriptor in a set and send a message to |
+ // the recipient, which is queued AFTER the message that |
+ // sent the FD. The recipient will reply to the message, |
+ // letting us know that it is now safe to close the file |
+ // descriptor. For more information, see: |
+ // http://crbug.com/298276 |
+ std::vector<int> fds; |
for (auto& handle : *handles) |
- handles_to_close_->push_back(handle); |
- } |
- MessagePtr fds_message( |
- new Channel::Message(sizeof(fds[0]) * fds.size(), 0, |
- Message::Header::MessageType::HANDLES_SENT)); |
- memcpy(fds_message->mutable_payload(), fds.data(), |
- sizeof(fds[0]) * fds.size()); |
- outgoing_messages_.emplace_back(std::move(fds_message), 0); |
- handles->clear(); |
+ fds.push_back(handle.handle); |
+ { |
+ base::AutoLock l(handles_to_close_lock_); |
+ for (auto& handle : *handles) |
+ handles_to_close_->push_back(handle); |
+ } |
+ MessagePtr fds_message( |
+ new Channel::Message(sizeof(fds[0]) * fds.size(), 0, |
+ Message::Header::MessageType::HANDLES_SENT)); |
+ memcpy(fds_message->mutable_payload(), fds.data(), |
+ sizeof(fds[0]) * fds.size()); |
+ outgoing_messages_.emplace_back(std::move(fds_message), 0); |
+ handles->clear(); |
#else |
- handles.reset(); |
+ handles.reset(); |
#endif // defined(OS_MACOSX) |
+ } |
} else { |
result = PlatformChannelWrite(handle_.get(), message_view.data(), |
message_view.data_num_bytes()); |
@@ -312,6 +318,7 @@ class ChannelPosix : public Channel, |
if (result < 0) { |
if (errno != EAGAIN && errno != EWOULDBLOCK) |
return false; |
+ message_view.SetHandles(std::move(handles)); |
outgoing_messages_.emplace_front(std::move(message_view)); |
WaitForWriteOnIOThreadNoLock(); |
return true; |