udp: add UV_UDP_MMSG_FREE recv_cb flag
Refs: https://github.com/libuv/libuv/issues/2822 PR-URL: https://github.com/libuv/libuv/pull/2836 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Jameson Nash <vtjnash@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
fa8b4f27c0
commit
ea17e1cffb
@ -47,6 +47,12 @@ Data types
|
||||
* must not be freed by the recv_cb callback.
|
||||
*/
|
||||
UV_UDP_MMSG_CHUNK = 8,
|
||||
/*
|
||||
* Indicates that the buffer provided has been fully utilized by recvmmsg and
|
||||
* that it should now be freed by the recv_cb callback. When this flag is set
|
||||
* in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL.
|
||||
*/
|
||||
UV_UDP_MMSG_FREE = 16,
|
||||
/*
|
||||
* Indicates that recvmmsg should be used, if available.
|
||||
*/
|
||||
@ -80,8 +86,10 @@ Data types
|
||||
When using :man:`recvmmsg(2)`, chunks will have the `UV_UDP_MMSG_CHUNK` flag set,
|
||||
those must not be freed. There will be a final callback with `nread` set to 0,
|
||||
`addr` set to NULL and the buffer pointing at the initially allocated data with
|
||||
the `UV_UDP_MMSG_CHUNK` flag cleared. This is a good chance for the callee to
|
||||
free the provided buffer.
|
||||
the `UV_UDP_MMSG_CHUNK` flag cleared and the `UV_UDP_MMSG_FREE` flag set.
|
||||
The callee can now safely free the provided buffer.
|
||||
|
||||
.. versionchanged:: 1.39.0 added the `UV_UDP_MMSG_FREE` flag.
|
||||
|
||||
.. note::
|
||||
The receive callback will be called with `nread` == 0 and `addr` == NULL when there is
|
||||
|
||||
@ -614,6 +614,12 @@ enum uv_udp_flags {
|
||||
* must not be freed by the recv_cb callback.
|
||||
*/
|
||||
UV_UDP_MMSG_CHUNK = 8,
|
||||
/*
|
||||
* Indicates that the buffer provided has been fully utilized by recvmmsg and
|
||||
* that it should now be freed by the recv_cb callback. When this flag is set
|
||||
* in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL.
|
||||
*/
|
||||
UV_UDP_MMSG_FREE = 16,
|
||||
|
||||
/*
|
||||
* Indicates that recvmmsg should be used, if available.
|
||||
|
||||
@ -238,7 +238,7 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
||||
|
||||
/* one last callback so the original buffer is freed */
|
||||
if (handle->recv_cb != NULL)
|
||||
handle->recv_cb(handle, 0, buf, NULL, 0);
|
||||
handle->recv_cb(handle, 0, buf, NULL, UV_UDP_MMSG_FREE);
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
@ -74,16 +74,22 @@ static void recv_cb(uv_udp_t* handle,
|
||||
unsigned flags) {
|
||||
ASSERT_GE(nread, 0);
|
||||
|
||||
if (nread > 0) {
|
||||
ASSERT_EQ(nread, 4);
|
||||
ASSERT(addr != NULL);
|
||||
ASSERT_MEM_EQ("PING", rcvbuf->base, nread);
|
||||
/* free and return if this is a mmsg free-only callback invocation */
|
||||
if (flags & UV_UDP_MMSG_FREE) {
|
||||
ASSERT_EQ(nread, 0);
|
||||
ASSERT(addr == NULL);
|
||||
free(rcvbuf->base);
|
||||
return;
|
||||
}
|
||||
|
||||
recv_cb_called++;
|
||||
if (recv_cb_called == NUM_SENDS) {
|
||||
uv_close((uv_handle_t*)handle, close_cb);
|
||||
uv_close((uv_handle_t*)&sender, close_cb);
|
||||
}
|
||||
ASSERT_EQ(nread, 4);
|
||||
ASSERT(addr != NULL);
|
||||
ASSERT_MEM_EQ("PING", rcvbuf->base, nread);
|
||||
|
||||
recv_cb_called++;
|
||||
if (recv_cb_called == NUM_SENDS) {
|
||||
uv_close((uv_handle_t*)handle, close_cb);
|
||||
uv_close((uv_handle_t*)&sender, close_cb);
|
||||
}
|
||||
|
||||
/* Don't free if the buffer could be reused via mmsg */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user