Skip to content

Commit

Permalink
Make a writemGSO API with just iovecs [1/n]
Browse files Browse the repository at this point in the history
Summary:
**Background for the diff stack**: We'd like to excise the usage of folly from a library that we maintain (quic), which is why we'd like to have a version of `writemGSO` that takes in iovecs instead of IOBufs.

**What this diff is doing**: I'd like to use `fillMsgVec` within the version of `writemGSO` that takes in iovecs instead of IOBufs. So, I'm separating out the IOBuf-filling functionality of `fillMsgVec` into a separate function.

Reviewed By: jbeshay

Differential Revision: D67873285

fbshipit-source-id: 519a68e97aba878bb52818d63afd95eb75b8ce26
  • Loading branch information
Aman Sharma authored and facebook-github-bot committed Jan 22, 2025
1 parent 9b71bc3 commit 249d914
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 25 deletions.
45 changes: 21 additions & 24 deletions folly/io/async/AsyncUDPSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -865,25 +865,35 @@ int AsyncUDPSocket::writemGSO(
return ret;
}

void AsyncUDPSocket::fillIoVec(
const std::unique_ptr<folly::IOBuf>* bufs,
struct iovec* iov,
size_t count,
size_t iov_count) {
size_t remaining = iov_count;
size_t iov_pos = 0;
for (size_t i = 0; i < count; i++) {
auto ret = bufs[i]->fillIov(&iov[iov_pos], remaining);
size_t iovec_len = ret.numIovecs;
remaining -= iovec_len;
iov_pos += iovec_len;
}
}

void AsyncUDPSocket::fillMsgVec(
Range<full_sockaddr_storage*> addrs,
const std::unique_ptr<folly::IOBuf>* bufs,
size_t count,
struct mmsghdr* msgvec,
struct iovec* iov,
size_t iov_count,
const WriteOptions* options,
char* control) {
auto addr_count = addrs.size();
DCHECK(addr_count);
size_t remaining = iov_count;

size_t iov_pos = 0;
for (size_t i = 0; i < count; i++) {
// we can use remaining here to avoid calling countChainElements() again
auto ret = bufs[i]->fillIov(&iov[iov_pos], remaining);
size_t iovec_len = ret.numIovecs;
remaining -= iovec_len;
auto& msg = msgvec[i].msg_hdr;
// if we have less addrs compared to count
// we use the last addr
Expand All @@ -895,7 +905,7 @@ void AsyncUDPSocket::fillMsgVec(
msg.msg_namelen = addrs[addr_count - 1].len;
}
msg.msg_iov = &iov[iov_pos];
msg.msg_iovlen = iovec_len;
msg.msg_iovlen = bufs[i]->countChainElements();
#ifdef FOLLY_HAVE_MSG_ERRQUEUE
size_t controlBufSize = 1 +
cmsgs_->size() *
Expand Down Expand Up @@ -972,7 +982,7 @@ void AsyncUDPSocket::fillMsgVec(

msgvec[i].msg_len = 0;

iov_pos += iovec_len;
iov_pos += bufs[i]->countChainElements();
}
}

Expand Down Expand Up @@ -1006,27 +1016,14 @@ int AsyncUDPSocket::writeImpl(
FOLLY_GNU_DISABLE_WARNING("-Wvla")
iovec iov[BOOST_PP_IF(FOLLY_HAVE_VLA_01, iov_count, kSmallSizeMax)];
FOLLY_POP_WARNING
fillMsgVec(
range(addrStorage),
bufs,
count,
msgvec,
iov,
iov_count,
options,
control);
fillIoVec(bufs, iov, count, iov_count);
fillMsgVec(range(addrStorage), bufs, count, msgvec, iov, options, control);
ret = sendmmsg(fd_, msgvec, count, 0);
} else {
std::unique_ptr<iovec[]> iov(new iovec[iov_count]);
fillIoVec(bufs, iov.get(), count, iov_count);
fillMsgVec(
range(addrStorage),
bufs,
count,
msgvec,
iov.get(),
iov_count,
options,
control);
range(addrStorage), bufs, count, msgvec, iov.get(), options, control);
ret = sendmmsg(fd_, msgvec, count, 0);
}

Expand Down
7 changes: 6 additions & 1 deletion folly/io/async/AsyncUDPSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,13 +541,18 @@ class AsyncUDPSocket : public EventHandler {
return netops_->sendmmsg(socket, msgvec, vlen, flags);
}

void fillIoVec(
const std::unique_ptr<folly::IOBuf>* bufs,
struct iovec* iov,
size_t count,
size_t iov_count);

void fillMsgVec(
Range<full_sockaddr_storage*> addrs,
const std::unique_ptr<folly::IOBuf>* bufs,
size_t count,
struct mmsghdr* msgvec,
struct iovec* iov,
size_t iov_count,
const WriteOptions* options,
char* control);

Expand Down

0 comments on commit 249d914

Please sign in to comment.