io: make libuv more 64-bit safe (#5078)

Continuation of #5076, for the required breaking changes to make
write_queue_size also safe internally for I/O on 32-bit machines.
This commit is contained in:
Jameson Nash 2026-03-19 21:09:06 -04:00 committed by GitHub
parent a265c3e405
commit f59cbd58da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 21 additions and 8 deletions

View File

@ -282,7 +282,7 @@ API
.. warning:: Don't call libuv functions after calling .. warning:: Don't call libuv functions after calling
:c:func:`uv_library_shutdown()`. :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`. 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 `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. 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) .. c:function:: char** uv_setup_args(int argc, char** argv)
Store the program arguments. Required for getting / setting the process title Store the program arguments. Required for getting / setting the process title

View File

@ -78,10 +78,12 @@ Data types
Public members 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. 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 .. c:member:: uv_stream_t* uv_connect_t.handle
Pointer to the stream where this connection request is running. Pointer to the stream where this connection request is running.
@ -254,10 +256,11 @@ API
.. versionchanged:: 1.4.0 UNIX implementation added. .. 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`. Returns `stream->write_queue_size`.
.. versionadded:: 1.19.0 .. versionadded:: 1.19.0
.. versionchanged:: 2.0.0 Return type made uint64_t
.. seealso:: The :c:type:`uv_handle_t` API functions also apply. .. 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 \ #define UV_STREAM_FIELDS \
/* number of bytes queued for writing */ \ /* number of bytes queued for writing */ \
size_t write_queue_size; \ uint64_t write_queue_size; \
uv_alloc_cb alloc_cb; \ uv_alloc_cb alloc_cb; \
uv_read_cb read_cb; \ uv_read_cb read_cb; \
/* private */ \ /* private */ \
@ -580,7 +580,7 @@ struct uv_stream_s {
UV_STREAM_FIELDS 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_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client); 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 uv_buf_init(char* base, size_t len) {
uv_buf_t buf; uv_buf_t buf;
buf.base = base; buf.base = base;
buf.len = len; buf.len = len > INT32_MAX ? INT32_MAX : len;
return buf; return buf;
} }

View File

@ -78,7 +78,7 @@ void uv_req_set_data(uv_req_t* req, void* data) {
req->data = 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; return stream->write_queue_size;
} }

View File

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