io: make libuv more 64-bit safe

Continuation of jn/64-safe, for the required breaking changes to make
write_queue_size also safe internally for I/O on 32-bit machines.

Refs: #5076
This commit is contained in:
Jameson Nash 2026-03-18 16:35:12 -04:00
parent 5ecd86c531
commit 45a82b425e
6 changed files with 21 additions and 8 deletions

View File

@ -282,7 +282,7 @@ API
.. warning:: Don't call libuv functions after calling
:c:func:`uv_library_shutdown()`.
.. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len)
.. c:function:: uv_buf_t uv_buf_init(char* base, size_t len)
Constructor for :c:type:`uv_buf_t`.
@ -290,6 +290,8 @@ API
`base` and `len` members of the uv_buf_t struct. The user is responsible for
freeing `base` after the uv_buf_t is done. Return struct passed by value.
.. versionchanged:: 2.0.0 `buf.len` is capped to INT32_MAX.
.. c:function:: char** uv_setup_args(int argc, char** argv)
Store the program arguments. Required for getting / setting the process title

View File

@ -78,10 +78,12 @@ Data types
Public members
^^^^^^^^^^^^^^
.. c:member:: size_t uv_stream_t.write_queue_size
.. c:member:: uint64_t uv_stream_t.write_queue_size
Contains the amount of queued bytes waiting to be sent. Readonly.
.. versionchanged:: 2.0.0 Made uint64_t to avoid overflow.
.. c:member:: uv_stream_t* uv_connect_t.handle
Pointer to the stream where this connection request is running.
@ -254,10 +256,11 @@ API
.. versionchanged:: 1.4.0 UNIX implementation added.
.. c:function:: size_t uv_stream_get_write_queue_size(const uv_stream_t* stream)
.. c:function:: uint64_t uv_stream_get_write_queue_size(const uv_stream_t* stream)
Returns `stream->write_queue_size`.
.. versionadded:: 1.19.0
.. versionchanged:: 2.0.0 Return type made uint64_t
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.

View File

@ -562,7 +562,7 @@ UV_EXTERN int uv_socketpair(int type,
#define UV_STREAM_FIELDS \
/* number of bytes queued for writing */ \
size_t write_queue_size; \
uint64_t write_queue_size; \
uv_alloc_cb alloc_cb; \
uv_read_cb read_cb; \
/* private */ \
@ -580,7 +580,7 @@ struct uv_stream_s {
UV_STREAM_FIELDS
};
UV_EXTERN size_t uv_stream_get_write_queue_size(const uv_stream_t* stream);
UV_EXTERN uint64_t uv_stream_get_write_queue_size(const uv_stream_t* stream);
UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client);

View File

@ -191,7 +191,7 @@ size_t uv_loop_size(void) {
uv_buf_t uv_buf_init(char* base, size_t len) {
uv_buf_t buf;
buf.base = base;
buf.len = len;
buf.len = len > INT32_MAX ? INT32_MAX : len;
return buf;
}

View File

@ -78,7 +78,7 @@ void uv_req_set_data(uv_req_t* req, void* data) {
req->data = data;
}
size_t uv_stream_get_write_queue_size(const uv_stream_t* stream) {
uint64_t uv_stream_get_write_queue_size(const uv_stream_t* stream) {
return stream->write_queue_size;
}

View File

@ -18,21 +18,29 @@
#include <stdint.h>
TEST_IMPL(buf_large) {
uv_buf_t buf;
buf = uv_buf_init(NULL, SIZE_MAX);
ASSERT(buf.len == INT32_MAX);
#ifdef _WIN32
WSABUF* wbuf;
wbuf = (WSABUF*) &buf;
ASSERT(wbuf->len == buf.len);
ASSERT(sizeof(uv_buf_t) == sizeof(WSABUF));
ASSERT(sizeof(((uv_buf_t*) 0)->base) ==
sizeof(((WSABUF*) 0)->buf));
ASSERT(sizeof(((uv_buf_t*) 0)->len) == sizeof(((WSABUF*) 0)->len));
ASSERT(offsetof(uv_buf_t, base) == offsetof(WSABUF, buf));
ASSERT(offsetof(uv_buf_t, len) == offsetof(WSABUF, len));
#else
struct iovec* iobuf;
iobuf = (struct iovec*) &buf;
ASSERT(iobuf->iov_len == buf.len);
ASSERT(buf.len == SIZE_MAX);
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec));