Skip to content

Commit

Permalink
Bump Libuv to 1.50.0
Browse files Browse the repository at this point in the history
  • Loading branch information
squeek502 committed Jan 16, 2025
1 parent 1ca0af2 commit 95a34d8
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 3 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.10)
project (luv C ASM)

set(LUV_VERSION_MAJOR 1)
set(LUV_VERSION_MINOR 49)
set(LUV_VERSION_PATCH 2)
set(LUV_VERSION_MINOR 50)
set(LUV_VERSION_PATCH 0)
set(LUV_VERSION ${LUV_VERSION_MAJOR}.${LUV_VERSION_MINOR}.${LUV_VERSION_PATCH})

if(NOT ${CMAKE_VERSION} VERSION_LESS "3.5.0")
Expand Down
2 changes: 1 addition & 1 deletion deps/libuv
Submodule libuv updated 60 files
+69 −66 .github/workflows/CI-unix.yml
+1 −1 .github/workflows/sanitizer.yml
+1 −0 .mailmap
+3 −1 AUTHORS
+3 −2 CMakeLists.txt
+82 −1 ChangeLog
+1 −0 LINKS.md
+3 −3 MAINTAINERS.md
+2 −1 Makefile.am
+2 −2 SUPPORTED_PLATFORMS.md
+1 −1 configure.ac
+5 −0 docs/src/fs_event.rst
+11 −0 docs/src/misc.rst
+25 −0 docs/src/threading.rst
+2 −0 docs/src/threadpool.rst
+9 −5 docs/src/timer.rst
+14 −0 docs/src/udp.rst
+12 −0 include/uv.h
+6 −0 include/uv/errno.h
+4 −1 include/uv/unix.h
+2 −2 include/uv/version.h
+1 −9 include/uv/win.h
+3 −0 src/fs-poll.c
+1 −1 src/idna.c
+1 −0 src/threadpool.c
+83 −0 src/unix/async.c
+47 −3 src/unix/core.c
+2 −18 src/unix/darwin-proctitle.c
+24 −0 src/unix/internal.h
+17 −12 src/unix/kqueue.c
+45 −30 src/unix/linux.c
+9 −21 src/unix/pipe.c
+98 −0 src/unix/thread.c
+201 −186 src/unix/udp.c
+22 −0 src/uv-common.c
+20 −0 src/uv-common.h
+8 −102 src/win/core.c
+4 −0 src/win/fs-event.c
+197 −8 src/win/fs.c
+9 −3 src/win/pipe.c
+74 −0 src/win/thread.c
+20 −1 src/win/udp.c
+68 −24 src/win/util.c
+0 −13 src/win/winapi.c
+54 −54 src/win/winapi.h
+0 −41 src/win/winsock.h
+14 −0 test/runner.c
+8 −1 test/test-fs-event.c
+54 −0 test/test-fs.c
+19 −7 test/test-idna.c
+10 −0 test/test-list.h
+9 −0 test/test-pipe-getsockname.c
+16 −0 test/test-platform-output.c
+2 −4 test/test-spawn.c
+189 −0 test/test-thread-name.c
+10 −0 test/test-thread.c
+3 −2 test/test-udp-mmsg.c
+17 −2 test/test-udp-multicast-join.c
+1 −0 test/test-udp-multicast-join6.c
+34 −6 test/test-udp-try-send.c
48 changes: 48 additions & 0 deletions docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -2464,6 +2464,54 @@ completed immediately.

**Returns:** `integer` or `fail`

### `uv.udp_try_send2(udp, messages, flags)`

> method form `udp:try_send2(messages, flags)`
**Parameters:**
- `udp`: `uv_udp_t userdata`
- `messages`: `table`
- `[1, 2, 3, ..., n]` : `table`
- `data` : `buffer`
- `addr` : `table`
- `ip` : `string`
- `port` : `integer`
- `flags`: `nil` (see below)
- `port`: `integer`

Like `uv.udp_try_send()`, but can send multiple datagrams.
Lightweight abstraction around `sendmmsg(2)`, with a `sendmsg(2)` fallback loop
for platforms that do not support the former.

`messages` should be an array-like table, where `addr` must be specified
if the `udp` has not already been connected via `udp_connect` (otherwise, it
must be `nil`).

`flags` is reserved for future extension and must currently be `nil` or `0` or
`{}`.

Returns the number of messages sent successfully. An error will only be returned
if the first datagram failed to be sent.

**Returns:** `integer` or `fail`

```lua
-- If client:connect() was not called
local addr = { ip = "127.0.0.1", port = 1234 }
client:try_send2({
{ data = "Message 1", addr = addr },
{ data = "Message 2", addr = addr },
{ data = "Message 3", addr = addr },
})

-- If client:connect() was called
client:try_send2({
{ data = "Message 1" },
{ data = "Message 2" },
{ data = "Message 3" },
})
```

### `uv.udp_recv_start(udp, callback)`

> method form `udp:recv_start(callback)`
Expand Down
6 changes: 6 additions & 0 deletions src/luv.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ static const luaL_Reg luv_functions[] = {
{"udp_set_ttl", luv_udp_set_ttl},
{"udp_send", luv_udp_send},
{"udp_try_send", luv_udp_try_send},
#if LUV_UV_VERSION_GEQ(1, 50, 0)
{"udp_try_send2", luv_udp_try_send2},
#endif
{"udp_recv_start", luv_udp_recv_start},
{"udp_recv_stop", luv_udp_recv_stop},
#if LUV_UV_VERSION_GEQ(1, 27, 0)
Expand Down Expand Up @@ -585,6 +588,9 @@ static const luaL_Reg luv_udp_methods[] = {
{"set_ttl", luv_udp_set_ttl},
{"send", luv_udp_send},
{"try_send", luv_udp_try_send},
#if LUV_UV_VERSION_GEQ(1, 50, 0)
{"try_send2", luv_udp_try_send2},
#endif
{"recv_start", luv_udp_recv_start},
{"recv_stop", luv_udp_recv_stop},
#if LUV_UV_VERSION_GEQ(1, 27, 0)
Expand Down
68 changes: 68 additions & 0 deletions src/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,74 @@ static int luv_udp_try_send(lua_State* L) {
return 1;
}

#if LUV_UV_VERSION_GEQ(1, 50, 0)
static int luv_udp_try_send2(lua_State* L) {
uv_udp_t* handle = luv_check_udp(L, 1);
int err_or_num_datagrams_sent;
unsigned int num_msgs;
// to-be-allocated with the length of num_msgs
struct sockaddr_storage* addrs;
struct sockaddr** addr_ptrs;
unsigned int* counts;
uv_buf_t** bufs;
unsigned int flags = 0;

luaL_checktype(L, 2, LUA_TTABLE);
num_msgs = lua_rawlen(L, 2);

// flags param can be nil, an integer, or a table
if (lua_type(L, 3) == LUA_TNUMBER || lua_isnoneornil(L, 3)) {
flags = (unsigned int)luaL_optinteger(L, 3, 0);
}
else if (lua_type(L, 3) == LUA_TTABLE) {
// this is for forwards-compatibility: if flags ever get added,
// we want to be able to take a table
}
else {
return luaL_argerror(L, 3, "expected nil, integer, or table");
}

addrs = malloc(sizeof(struct sockaddr_storage) * num_msgs);
addr_ptrs = malloc(sizeof(struct sockaddr_storage*) * num_msgs);
counts = malloc(sizeof(unsigned int) * num_msgs);
bufs = malloc(sizeof(uv_buf_t*) * num_msgs);
for (unsigned int i=0; i<num_msgs; i++) {
lua_rawgeti(L, 2, i+1);
int element_index = lua_gettop(L);
lua_getfield(L, element_index, "data");
size_t count;
bufs[i] = luv_check_bufs_noref(L, -1, &count);
if (count > UINT_MAX)
return luaL_error(L, "data at index %d contains too many bufs (max is %d)", UINT_MAX);
counts[i] = count;
lua_pop(L, 1);
lua_getfield(L, element_index, "addr");
int addr_index = lua_gettop(L);
if (!lua_isnoneornil(L, addr_index)) {
lua_getfield(L, addr_index, "ip");
lua_getfield(L, addr_index, "port");
addr_ptrs[i] = luv_check_addr(L, &addrs[i], -2, -1);
lua_pop(L, 4); // ip, port, addr, and current array element
}
else {
addr_ptrs[i] = NULL;
lua_pop(L, 2); // addr and current array element
}
}
err_or_num_datagrams_sent = uv_udp_try_send2(handle, num_msgs, bufs, counts, addr_ptrs, flags);
free(addrs);
free(addr_ptrs);
free(counts);
for (unsigned int i=0; i<num_msgs; i++)
free(bufs[i]);
free(bufs);

if (err_or_num_datagrams_sent < 0) return luv_error(L, err_or_num_datagrams_sent);
lua_pushinteger(L, err_or_num_datagrams_sent);
return 1;
}
#endif

static void luv_udp_recv_cb(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) {
luv_handle_t* data = (luv_handle_t*)handle->data;
lua_State* L = data->ctx->L;
Expand Down
74 changes: 74 additions & 0 deletions tests/test-udp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,78 @@ return require('lib/tap')(function (test)
assert(sender:try_send("PING", "127.0.0.1", TEST_PORT))
end
end, "1.39.0")

local function udp_try_send2_test(should_connect)
return function(print, p, expect, uv)
-- If udp_connect is called on the sender, then addr cannot be specified in any messages.
-- Otherwise, it *must* be specified in every message.
local send_addr = { ip = "127.0.0.1", port = TEST_PORT }
local msgs_to_send = {
{ data = "PING", addr = send_addr },
{ data = "PING", addr = send_addr },
{ data = "PING", addr = send_addr },
-- Add in a message that goes to a different address to ensure that
-- messages having a different address are allowed (when not connected)
{ data = "PING", addr = { ip = "127.0.0.1", port = TEST_PORT + 1 } },
{ data = { "P", "I", "N", "G" }, addr = send_addr },
}
local expected_msgs = #msgs_to_send
if not should_connect then
expected_msgs = expected_msgs - 1
end
-- Remove addr from the messages if we are calling udp_connect
if should_connect then
for _,v in ipairs(msgs_to_send) do
v.addr = nil
end
end

local recver = uv.new_udp()
assert(recver:bind("0.0.0.0", TEST_PORT))

local sender = uv.new_udp()
if should_connect then
assert(uv.udp_connect(sender, send_addr.ip, send_addr.port))
end

local msgs_recved = 0
local recv_cb = function(err, data, addr, flags)
assert(not err, err)
p(data, addr)

-- empty callback can happen, just return early
if data == nil and addr == nil then
return
end

assert(addr)
assert(data == "PING")

msgs_recved = msgs_recved + 1
if msgs_recved == expected_msgs then
sender:close()
recver:close()
end
end

assert(recver:recv_start(recv_cb))
while #msgs_to_send > 0 do
local num_sent = assert(sender:try_send2(msgs_to_send))
print('sent '..num_sent..' out of '..#msgs_to_send..', expecting '..expected_msgs..' to be received')
for _=1,num_sent do
table.remove(msgs_to_send, 1)
end
end
end
end

test("udp try_send2 not connected", function(print, p, expect, uv)
local testfn = udp_try_send2_test(false)
return testfn(print, p, expect, uv)
end, "1.50.0")

test("udp try_send2 connected", function(print, p, expect, uv)
local testfn = udp_try_send2_test(true)
return testfn(print, p, expect, uv)
end, "1.50.0")
end)

0 comments on commit 95a34d8

Please sign in to comment.