darwin: add udp mmsg support (#4527)

This commit is contained in:
Raihaan Shouhell 2024-09-18 05:15:37 +08:00 committed by GitHub
parent 5bb19f35ea
commit 1c778bd001
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 9 deletions

View File

@ -0,0 +1,17 @@
#ifndef UV_DARWIN_SYSCALLS_H_
#define UV_DARWIN_SYSCALLS_H_
#include <sys/types.h>
#include <sys/socket.h>
/* https://github.com/apple/darwin-xnu/blob/master/bsd/sys/socket.h */
struct mmsghdr {
struct msghdr msg_hdr;
size_t msg_len;
};
ssize_t recvmsg_x(int s, const struct mmsghdr* msgp, u_int cnt, int flags);
ssize_t sendmsg_x(int s, const struct mmsghdr* msgp, u_int cnt, int flags);
#endif /* UV_DARWIN_SYSCALLS_H_ */

View File

@ -75,8 +75,11 @@
# include <poll.h>
#endif /* _AIX */
#if defined(__APPLE__) && !TARGET_OS_IPHONE
# include <AvailabilityMacros.h>
#if defined(__APPLE__)
# include "darwin-syscalls.h"
# if !TARGET_OS_IPHONE
# include <AvailabilityMacros.h>
# endif
#endif
/*

View File

@ -148,7 +148,7 @@ static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
}
static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
#if defined(__linux__) || defined(__FreeBSD__)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
struct sockaddr_in6 peers[20];
struct iovec iov[ARRAY_SIZE(peers)];
struct mmsghdr msgs[ARRAY_SIZE(peers)];
@ -173,11 +173,18 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
msgs[k].msg_hdr.msg_control = NULL;
msgs[k].msg_hdr.msg_controllen = 0;
msgs[k].msg_hdr.msg_flags = 0;
msgs[k].msg_len = 0;
}
#if defined(__APPLE__)
do
nread = recvmsg_x(handle->io_watcher.fd, msgs, chunks, MSG_DONTWAIT);
while (nread == -1 && errno == EINTR);
#else
do
nread = recvmmsg(handle->io_watcher.fd, msgs, chunks, 0, NULL);
while (nread == -1 && errno == EINTR);
#endif
if (nread < 1) {
if (nread == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
@ -204,9 +211,9 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
handle->recv_cb(handle, 0, buf, NULL, UV_UDP_MMSG_FREE);
}
return nread;
#else /* __linux__ || ____FreeBSD__ */
#else /* __linux__ || ____FreeBSD__ || __APPLE__ */
return UV_ENOSYS;
#endif /* __linux__ || ____FreeBSD__ */
#endif /* __linux__ || ____FreeBSD__ || __APPLE__ */
}
static void uv__udp_recvmsg(uv_udp_t* handle) {
@ -328,7 +335,7 @@ static void uv__udp_sendmsg_one(uv_udp_t* handle, uv_udp_send_t* req) {
}
}
#if defined(__linux__) || defined(__FreeBSD__)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
static void uv__udp_sendmsg_many(uv_udp_t* handle) {
uv_udp_send_t* req;
struct mmsghdr h[20];
@ -366,9 +373,15 @@ write_queue_drain:
h[pkts].msg_hdr.msg_iovlen = req->nbufs;
}
#if defined(__APPLE__)
do
npkts = sendmsg_x(handle->io_watcher.fd, h, pkts, MSG_DONTWAIT);
while (npkts == -1 && errno == EINTR);
#else
do
npkts = sendmmsg(handle->io_watcher.fd, h, pkts, 0);
while (npkts == -1 && errno == EINTR);
#endif
if (npkts < 1) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
@ -409,7 +422,7 @@ write_queue_drain:
uv__io_feed(handle->loop, &handle->io_watcher);
}
#endif /* __linux__ || ____FreeBSD__ */
#endif /* __linux__ || ____FreeBSD__ || __APPLE__ */
static void uv__udp_sendmsg(uv_udp_t* handle) {
struct uv__queue* q;
@ -421,7 +434,7 @@ static void uv__udp_sendmsg(uv_udp_t* handle) {
q = uv__queue_head(&handle->write_queue);
req = uv__queue_data(q, uv_udp_send_t, queue);
#if defined(__linux__) || defined(__FreeBSD__)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
/* Use sendmmsg() if this send request contains more than one datagram OR
* there is more than one send request (because that automatically implies
* there is more than one datagram.)
@ -1037,7 +1050,7 @@ int uv__udp_init_ex(uv_loop_t* loop,
int uv_udp_using_recvmmsg(const uv_udp_t* handle) {
#if defined(__linux__) || defined(__FreeBSD__)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
if (handle->flags & UV_HANDLE_UDP_RECVMMSG)
return 1;
#endif