aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2024-12-10 23:36:32 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2024-12-13 21:52:59 +0100
commite8969bff6cfebf950b2a52eabff53e53ff02ab0e (patch)
tree2129475b3a9082e9da228c127a7c811db81a1ec1 /src
parent7b4cf04a914116d998c5ebcbf2d53b6848b2f65e (diff)
downloadlibuv-e8969bff6cfebf950b2a52eabff53e53ff02ab0e.tar.gz
libuv-e8969bff6cfebf950b2a52eabff53e53ff02ab0e.zip
unix,win: add uv_udp_try_send2
Add a version of uv_udp_try_send that can send multiple datagrams. Uses sendmmsg(2) on platforms that support it (Linux, FreeBSD, macOS), falls back to a regular sendmsg(2) loop elsewhere. This work was sponsored by ISC, the Internet Systems Consortium.
Diffstat (limited to 'src')
-rw-r--r--src/unix/udp.c15
-rw-r--r--src/uv-common.c19
-rw-r--r--src/uv-common.h6
-rw-r--r--src/win/udp.c18
4 files changed, 58 insertions, 0 deletions
diff --git a/src/unix/udp.c b/src/unix/udp.c
index 045e5fe8..67c01f7d 100644
--- a/src/unix/udp.c
+++ b/src/unix/udp.c
@@ -1401,3 +1401,18 @@ again:
feed:
uv__io_feed(handle->loop, &handle->io_watcher);
}
+
+
+int uv__udp_try_send2(uv_udp_t* handle,
+ unsigned int count,
+ uv_buf_t* bufs[/*count*/],
+ unsigned int nbufs[/*count*/],
+ struct sockaddr* addrs[/*count*/]) {
+ int fd;
+
+ fd = handle->io_watcher.fd;
+ if (fd == -1)
+ return UV_EINVAL;
+
+ return uv__udp_sendmsgv(fd, count, bufs, nbufs, addrs);
+}
diff --git a/src/uv-common.c b/src/uv-common.c
index 327e142c..60ff56b9 100644
--- a/src/uv-common.c
+++ b/src/uv-common.c
@@ -514,6 +514,25 @@ int uv_udp_try_send(uv_udp_t* handle,
}
+int uv_udp_try_send2(uv_udp_t* handle,
+ unsigned int count,
+ uv_buf_t* bufs[/*count*/],
+ unsigned int nbufs[/*count*/],
+ struct sockaddr* addrs[/*count*/],
+ unsigned int flags) {
+ if (count < 1)
+ return UV_EINVAL;
+
+ if (flags != 0)
+ return UV_EINVAL;
+
+ if (handle->send_queue_count > 0)
+ return UV_EAGAIN;
+
+ return uv__udp_try_send2(handle, count, bufs, nbufs, addrs);
+}
+
+
int uv_udp_recv_start(uv_udp_t* handle,
uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb) {
diff --git a/src/uv-common.h b/src/uv-common.h
index 10df1706..372f0c4b 100644
--- a/src/uv-common.h
+++ b/src/uv-common.h
@@ -191,6 +191,12 @@ int uv__udp_try_send(uv_udp_t* handle,
const struct sockaddr* addr,
unsigned int addrlen);
+int uv__udp_try_send2(uv_udp_t* handle,
+ unsigned int count,
+ uv_buf_t* bufs[/*count*/],
+ unsigned int nbufs[/*count*/],
+ struct sockaddr* addrs[/*count*/]);
+
int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloccb,
uv_udp_recv_cb recv_cb);
diff --git a/src/win/udp.c b/src/win/udp.c
index 557b4e60..e0873c2a 100644
--- a/src/win/udp.c
+++ b/src/win/udp.c
@@ -1142,3 +1142,21 @@ int uv__udp_try_send(uv_udp_t* handle,
return bytes;
}
+
+
+int uv__udp_try_send2(uv_udp_t* handle,
+ unsigned int count,
+ uv_buf_t* bufs[/*count*/],
+ unsigned int nbufs[/*count*/],
+ struct sockaddr* addrs[/*count*/]) {
+ unsigned int i;
+ int r;
+
+ for (i = 0; i < count; i++) {
+ r = uv_udp_try_send(handle, bufs[i], nbufs[i], addrs[i]);
+ if (r < 0)
+ return i > 0 ? i : r; /* Error if first packet, else send count. */
+ }
+
+ return i;
+}