Skip to content

Commit 70639a1

Browse files
Fix Windows MSVC build for WSABUF scatter-gather IO
Use a make_iovec helper for WSABUF fields on Windows, fix send_buf to set buf/len instead of iov_base/iov_len, call NUClear::sendmsg on Windows, and omit msg_flags where WSAMSG has no flags member. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 88933ed commit 70639a1

2 files changed

Lines changed: 38 additions & 11 deletions

File tree

src/nuclearnet/NUClearNet.cpp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@
4343
namespace NUClear {
4444
namespace network {
4545

46+
namespace {
47+
48+
iovec make_iovec(void* base, std::size_t len) {
49+
#ifdef _WIN32
50+
iovec iov{};
51+
iov.buf = reinterpret_cast<CHAR*>(base); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
52+
iov.len = static_cast<ULONG>(len);
53+
return iov;
54+
#else
55+
iovec iov{};
56+
iov.iov_base = base;
57+
iov.iov_len = len;
58+
return iov;
59+
#endif
60+
}
61+
62+
} // namespace
63+
4664
const std::chrono::milliseconds NUClearNet::ANNOUNCE_INTERVAL(500); // NOLINT(cert-err58-cpp)
4765

4866
NUClearNet::NUClearNet()
@@ -268,11 +286,10 @@ namespace network {
268286
header.flags = req.flags;
269287
header.hash = req.hash;
270288

271-
std::array<iovec, 2> iov{};
272-
iov[0].iov_base = reinterpret_cast<char*>(&header); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
273-
iov[0].iov_len = static_cast<decltype(iov[0].iov_len)>(sizeof(DataPacket) - 1);
274-
iov[1].iov_base = const_cast<char*>(reinterpret_cast<const char*>(req.data.data())); // NOLINT(cppcoreguidelines-pro-type-const-cast,cppcoreguidelines-pro-type-reinterpret-cast)
275-
iov[1].iov_len = static_cast<decltype(iov[1].iov_len)>(req.data.size());
289+
std::array<iovec, 2> iov{
290+
make_iovec(reinterpret_cast<void*>(&header), sizeof(DataPacket) - 1), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
291+
make_iovec(const_cast<void*>(static_cast<const void*>(req.data.data())), req.data.size()), // NOLINT(cppcoreguidelines-pro-type-const-cast)
292+
};
276293

277294
send_iov(data_fd, req.target, iov.data(), static_cast<int>(iov.size()));
278295
}
@@ -321,11 +338,10 @@ namespace network {
321338
const std::size_t offset = static_cast<std::size_t>(i) * packet_mtu;
322339
const std::size_t frag_len = std::min(static_cast<std::size_t>(packet_mtu), length - offset);
323340

324-
std::array<iovec, 2> iov{};
325-
iov[0].iov_base = reinterpret_cast<char*>(&header); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
326-
iov[0].iov_len = static_cast<decltype(iov[0].iov_len)>(sizeof(DataPacket) - 1);
327-
iov[1].iov_base = const_cast<char*>(reinterpret_cast<const char*>(payload + offset)); // NOLINT(cppcoreguidelines-pro-type-const-cast,cppcoreguidelines-pro-type-reinterpret-cast)
328-
iov[1].iov_len = static_cast<decltype(iov[1].iov_len)>(frag_len);
341+
std::array<iovec, 2> iov{
342+
make_iovec(reinterpret_cast<void*>(&header), sizeof(DataPacket) - 1), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
343+
make_iovec(const_cast<void*>(static_cast<const void*>(payload + offset)), frag_len), // NOLINT(cppcoreguidelines-pro-type-const-cast)
344+
};
329345

330346
send_iov(data_fd, dest, iov.data(), static_cast<int>(iov.size()));
331347
}
@@ -631,9 +647,15 @@ namespace network {
631647
msg.msg_iovlen = static_cast<decltype(msg.msg_iovlen)>(iovcnt);
632648
msg.msg_control = nullptr;
633649
msg.msg_controllen = 0;
634-
msg.msg_flags = 0;
650+
#ifndef _WIN32
651+
msg.msg_flags = 0;
652+
#endif
635653

654+
#ifdef _WIN32
655+
NUClear::sendmsg(fd, &msg, 0);
656+
#else
636657
::sendmsg(fd, &msg, 0);
658+
#endif
637659
}
638660

639661
} // namespace network

src/nuclearnet/NUClearNet.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,13 @@ namespace network {
198198
/// Send a single contiguous buffer to a target
199199
void send_buf(fd_t fd, const sock_t& target, const uint8_t* data, std::size_t length) {
200200
std::array<iovec, 1> iov{};
201+
#ifdef _WIN32
202+
iov[0].buf = reinterpret_cast<CHAR*>(const_cast<uint8_t*>(data)); // NOLINT(cppcoreguidelines-pro-type-const-cast)
203+
iov[0].len = static_cast<ULONG>(length);
204+
#else
201205
iov[0].iov_base = const_cast<char*>(reinterpret_cast<const char*>(data)); // NOLINT(cppcoreguidelines-pro-type-const-cast,cppcoreguidelines-pro-type-reinterpret-cast)
202206
iov[0].iov_len = static_cast<decltype(iov[0].iov_len)>(length);
207+
#endif
203208
send_iov(fd, target, iov.data(), 1);
204209
}
205210

0 commit comments

Comments
 (0)