Bug 1051567 - Make sure we resend file descriptors for the first chunk of a message. r=billm draft
authorKan-Ru Chen <kanru@kanru.info>
Tue, 30 Aug 2016 18:26:59 +0800
changeset 407850 e9ecd36912ab938023d2b7d665c377ee26a9320a
parent 407237 26e22af660e543ebb69930f082188b69ec756185
child 529968 d6e269c69410b360fc1064316183a6f3ddfd0dfa
push id28062
push userbmo:kchen@mozilla.com
push dateWed, 31 Aug 2016 04:17:41 +0000
reviewersbillm
bugs1051567, 1262671
milestone51.0a1
Bug 1051567 - Make sure we resend file descriptors for the first chunk of a message. r=billm Check if the buffers iterator was never consumed. This is a regression introduced when converting ipc to use BufferList in bug 1262671. MozReview-Commit-ID: LWAoVlI5CKJ
ipc/chromium/src/chrome/common/ipc_channel_posix.cc
mfbt/BufferList.h
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
@@ -574,17 +574,22 @@ bool Channel::ChannelImpl::ProcessOutgoi
     Message* msg = output_queue_.front();
 
     struct msghdr msgh = {0};
 
     static const int tmp = CMSG_SPACE(sizeof(
         int[FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE]));
     char buf[tmp];
 
-    if (partial_write_iter_.isNothing() &&
+    if (partial_write_iter_.isNothing()) {
+      Pickle::BufferList::IterImpl iter(msg->Buffers());
+      partial_write_iter_.emplace(iter);
+    }
+
+    if (partial_write_iter_.value().Data() == msg->Buffers().Start() &&
         !msg->file_descriptor_set()->empty()) {
       // This is the first chunk of a message which has descriptors to send
       struct cmsghdr *cmsg;
       const unsigned num_fds = msg->file_descriptor_set()->size();
 
       if (num_fds > FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE) {
         CHROMIUM_LOG(FATAL) << "Too many file descriptors!";
         // This should not be reached.
@@ -606,21 +611,16 @@ bool Channel::ChannelImpl::ProcessOutgoi
       msg->set_fd_cookie(++last_pending_fd_id_);
 #endif
     }
 
     struct iovec iov[kMaxIOVecSize];
     size_t iov_count = 0;
     size_t amt_to_write = 0;
 
-    if (partial_write_iter_.isNothing()) {
-      Pickle::BufferList::IterImpl iter(msg->Buffers());
-      partial_write_iter_.emplace(iter);
-    }
-
     // How much of this message have we written so far?
     Pickle::BufferList::IterImpl iter = partial_write_iter_.value();
 
     // Store the unwritten part of the first segment to write into the iovec.
     iov[0].iov_base = const_cast<char*>(iter.Data());
     iov[0].iov_len = iter.RemainingInSegment();
     amt_to_write += iov[0].iov_len;
     iter.Advance(msg->Buffers(), iov[0].iov_len);
--- a/mfbt/BufferList.h
+++ b/mfbt/BufferList.h
@@ -223,16 +223,17 @@ class BufferList : private AllocPolicy
     bool Done() const
     {
       return mData == mDataEnd;
     }
   };
 
   // Special convenience method that returns Iter().Data().
   char* Start() { return mSegments[0].mData; }
+  const char* Start() const { return mSegments[0].mData; }
 
   IterImpl Iter() const { return IterImpl(*this); }
 
   // Copies aSize bytes from aData into the BufferList. The storage for these
   // bytes may be split across multiple buffers. Size() is increased by aSize.
   inline bool WriteBytes(const char* aData, size_t aSize);
 
   // Copies possibly non-contiguous byte range starting at aIter into