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
--- 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