Bug 1051567 - Make sure we resend file descriptors for the first chunk of a message. r=billm
authorKan-Ru Chen <kanru@kanru.info>
Tue, 30 Aug 2016 18:26:59 +0800
changeset 312009 acb978a84753654b4deca915b12504f1c0c27fd0
parent 312008 5aaf198f4ee0b7deadb86c52c46a90a17c7e99c8
child 312010 2dcfc65b669237cd8629b4ef07a5287a66204580
push id30628
push userryanvm@gmail.com
push dateWed, 31 Aug 2016 13:53:01 +0000
treeherdermozilla-central@b38f935eb811 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1051567, 1262671
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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