udp: add flag to enable recvmmsg(2) explicitly
Instead of implicitly enabling it by checking the supplied buffer size to alloc_cb, have a dedicated flag that must be set on `uv_udp_init_ex`. Fixes: https://github.com/libuv/libuv/issues/2791 Closes: https://github.com/libuv/libuv/pull/2792 PR-URL: https://github.com/libuv/libuv/pull/2799 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
0fd993195f
commit
5736658bee
@ -41,12 +41,16 @@ Data types
|
|||||||
* (provided they all set the flag) but only the last one to bind will receive
|
* (provided they all set the flag) but only the last one to bind will receive
|
||||||
* any traffic, in effect "stealing" the port from the previous listener.
|
* any traffic, in effect "stealing" the port from the previous listener.
|
||||||
*/
|
*/
|
||||||
UV_UDP_REUSEADDR = 4
|
UV_UDP_REUSEADDR = 4,
|
||||||
/*
|
/*
|
||||||
* Indicates that the message was received by recvmmsg, so the buffer provided
|
* Indicates that the message was received by recvmmsg, so the buffer provided
|
||||||
* must not be freed by the recv_cb callback.
|
* must not be freed by the recv_cb callback.
|
||||||
*/
|
*/
|
||||||
UV_UDP_MMSG_CHUNK = 8
|
UV_UDP_MMSG_CHUNK = 8,
|
||||||
|
/*
|
||||||
|
* Indicates that recvmmsg should be used, if available.
|
||||||
|
*/
|
||||||
|
UV_UDP_RECVMMSG = 256
|
||||||
};
|
};
|
||||||
|
|
||||||
.. c:type:: void (*uv_udp_send_cb)(uv_udp_send_t* req, int status)
|
.. c:type:: void (*uv_udp_send_cb)(uv_udp_send_t* req, int status)
|
||||||
@ -125,12 +129,17 @@ API
|
|||||||
|
|
||||||
.. c:function:: int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags)
|
.. c:function:: int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags)
|
||||||
|
|
||||||
Initialize the handle with the specified flags. At the moment the lower 8 bits
|
Initialize the handle with the specified flags. The lower 8 bits of the `flags`
|
||||||
of the `flags` parameter are used as the socket domain. A socket will be created
|
parameter are used as the socket domain. A socket will be created for the given domain.
|
||||||
for the given domain. If the specified domain is ``AF_UNSPEC`` no socket is created,
|
If the specified domain is ``AF_UNSPEC`` no socket is created, just like :c:func:`uv_udp_init`.
|
||||||
just like :c:func:`uv_udp_init`.
|
|
||||||
|
The remaining bits can be used to set one of these flags:
|
||||||
|
|
||||||
|
* `UV_UDP_RECVMMSG`: if set, and the platform supports it, :man:`recvmmsg(2)` will
|
||||||
|
be used.
|
||||||
|
|
||||||
.. versionadded:: 1.7.0
|
.. versionadded:: 1.7.0
|
||||||
|
.. versionchanged:: 1.37.0 added the `UV_UDP_RECVMMSG` flag.
|
||||||
|
|
||||||
.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock)
|
.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock)
|
||||||
|
|
||||||
@ -379,6 +388,9 @@ API
|
|||||||
.. versionchanged:: 1.35.0 added support for :man:`recvmmsg(2)` on supported platforms).
|
.. versionchanged:: 1.35.0 added support for :man:`recvmmsg(2)` on supported platforms).
|
||||||
The use of this feature requires a buffer larger than
|
The use of this feature requires a buffer larger than
|
||||||
2 * 64KB to be passed to `alloc_cb`.
|
2 * 64KB to be passed to `alloc_cb`.
|
||||||
|
.. versionchanged:: 1.37.0 :man:`recvmmsg(2)` support is no longer enabled implicitly,
|
||||||
|
it must be explicitly requested by passing the `UV_UDP_RECVMMSG` flag to
|
||||||
|
:c:func:`uv_udp_init_ex`.
|
||||||
|
|
||||||
.. c:function:: int uv_udp_recv_stop(uv_udp_t* handle)
|
.. c:function:: int uv_udp_recv_stop(uv_udp_t* handle)
|
||||||
|
|
||||||
|
|||||||
@ -610,7 +610,12 @@ enum uv_udp_flags {
|
|||||||
* Indicates that the message was received by recvmmsg, so the buffer provided
|
* Indicates that the message was received by recvmmsg, so the buffer provided
|
||||||
* must not be freed by the recv_cb callback.
|
* must not be freed by the recv_cb callback.
|
||||||
*/
|
*/
|
||||||
UV_UDP_MMSG_CHUNK = 8
|
UV_UDP_MMSG_CHUNK = 8,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Indicates that recvmmsg should be used, if available.
|
||||||
|
*/
|
||||||
|
UV_UDP_RECVMMSG = 256
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
|
typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
|
||||||
|
|||||||
@ -262,11 +262,9 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
|
|||||||
assert(buf.base != NULL);
|
assert(buf.base != NULL);
|
||||||
|
|
||||||
#if HAVE_MMSG
|
#if HAVE_MMSG
|
||||||
uv_once(&once, uv__udp_mmsg_init);
|
if (handle->flags & UV_HANDLE_UDP_RECVMMSG) {
|
||||||
if (uv__recvmmsg_avail) {
|
uv_once(&once, uv__udp_mmsg_init);
|
||||||
/* Returned space for more than 1 datagram, use it to receive
|
if (uv__recvmmsg_avail) {
|
||||||
* multiple datagrams. */
|
|
||||||
if (buf.len >= 2 * UV__UDP_DGRAM_MAXSIZE) {
|
|
||||||
nread = uv__udp_recvmmsg(handle, &buf);
|
nread = uv__udp_recvmmsg(handle, &buf);
|
||||||
if (nread > 0)
|
if (nread > 0)
|
||||||
count -= nread;
|
count -= nread;
|
||||||
@ -949,6 +947,7 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle,
|
|||||||
int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
|
int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
|
||||||
int domain;
|
int domain;
|
||||||
int err;
|
int err;
|
||||||
|
int extra_flags;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* Use the lower 8 bits for the domain */
|
/* Use the lower 8 bits for the domain */
|
||||||
@ -956,7 +955,9 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
|
|||||||
if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
|
if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
|
||||||
if (flags & ~0xFF)
|
/* Use the higher bits for extra flags */
|
||||||
|
extra_flags = flags & ~0xFF;
|
||||||
|
if (extra_flags & ~UV_UDP_RECVMMSG)
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
|
||||||
if (domain != AF_UNSPEC) {
|
if (domain != AF_UNSPEC) {
|
||||||
@ -977,6 +978,9 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
|
|||||||
QUEUE_INIT(&handle->write_queue);
|
QUEUE_INIT(&handle->write_queue);
|
||||||
QUEUE_INIT(&handle->write_completed_queue);
|
QUEUE_INIT(&handle->write_completed_queue);
|
||||||
|
|
||||||
|
if (extra_flags & UV_UDP_RECVMMSG)
|
||||||
|
handle->flags |= UV_HANDLE_UDP_RECVMMSG;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -104,6 +104,7 @@ enum {
|
|||||||
/* Only used by uv_udp_t handles. */
|
/* Only used by uv_udp_t handles. */
|
||||||
UV_HANDLE_UDP_PROCESSING = 0x01000000,
|
UV_HANDLE_UDP_PROCESSING = 0x01000000,
|
||||||
UV_HANDLE_UDP_CONNECTED = 0x02000000,
|
UV_HANDLE_UDP_CONNECTED = 0x02000000,
|
||||||
|
UV_HANDLE_UDP_RECVMMSG = 0x04000000,
|
||||||
|
|
||||||
/* Only used by uv_pipe_t handles. */
|
/* Only used by uv_pipe_t handles. */
|
||||||
UV_HANDLE_NON_OVERLAPPED_PIPE = 0x01000000,
|
UV_HANDLE_NON_OVERLAPPED_PIPE = 0x01000000,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user