From cb2d5f3ffed75b02c57af3578940e389ffc71355 Mon Sep 17 00:00:00 2001 From: Edy Silva Date: Sun, 8 Mar 2026 23:15:59 -0300 Subject: [PATCH 1/4] unix: remove UV_HANDLE_READING flag --- src/unix/stream.c | 20 ++++++-------------- src/uv-common.c | 2 +- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/unix/stream.c b/src/unix/stream.c index 08a18314b..8bd241f47 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -930,7 +930,6 @@ static void uv__write_callbacks(uv_stream_t* stream) { static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) { stream->flags |= UV_HANDLE_READ_EOF; - stream->flags &= ~UV_HANDLE_READING; uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); uv__handle_stop(stream); uv__stream_osx_interrupt_select(stream); @@ -1037,11 +1036,7 @@ static void uv__read(uv_stream_t* stream) { is_ipc = stream->type == UV_NAMED_PIPE && ((uv_pipe_t*) stream)->ipc; - /* XXX: Maybe instead of having UV_HANDLE_READING we just test if - * tcp->read_cb is NULL or not? - */ while (stream->read_cb - && (stream->flags & UV_HANDLE_READING) && (count-- > 0)) { assert(stream->alloc_cb != NULL); @@ -1082,7 +1077,7 @@ static void uv__read(uv_stream_t* stream) { /* Error */ if (errno == EAGAIN || errno == EWOULDBLOCK) { /* Wait for the next one. */ - if (stream->flags & UV_HANDLE_READING) { + if (stream->read_cb != NULL) { uv__io_start(stream->loop, &stream->io_watcher, POLLIN); uv__stream_osx_interrupt_select(stream); } @@ -1096,8 +1091,9 @@ static void uv__read(uv_stream_t* stream) { /* Error. User should call uv_close(). */ stream->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); stream->read_cb(stream, UV__ERR(errno), &buf); - if (stream->flags & UV_HANDLE_READING) { - stream->flags &= ~UV_HANDLE_READING; + if (stream->read_cb != NULL) { + stream->read_cb = NULL; + stream->alloc_cb = NULL; uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); uv__handle_stop(stream); uv__stream_osx_interrupt_select(stream); @@ -1220,7 +1216,7 @@ void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { */ if ((events & POLLHUP) && !(events & POLLIN) && - (stream->flags & UV_HANDLE_READING) && + (stream->read_cb != NULL) && !(stream->flags & UV_HANDLE_READ_EOF)) { uv_buf_t buf = { NULL, 0 }; uv__stream_eof(stream, &buf); @@ -1450,9 +1446,6 @@ int uv__read_start(uv_stream_t* stream, assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE || stream->type == UV_TTY); - /* The UV_HANDLE_READING flag is irrelevant of the state of the stream - it - * just expresses the desired state of the user. */ - stream->flags |= UV_HANDLE_READING; stream->flags &= ~UV_HANDLE_READ_EOF; /* TODO: try to do the read inline? */ @@ -1471,10 +1464,9 @@ int uv__read_start(uv_stream_t* stream, int uv_read_stop(uv_stream_t* stream) { - if (!(stream->flags & UV_HANDLE_READING)) + if (stream->read_cb == NULL) return 0; - stream->flags &= ~UV_HANDLE_READING; uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); uv__handle_stop(stream); uv__stream_osx_interrupt_select(stream); diff --git a/src/uv-common.c b/src/uv-common.c index e5a763290..86d79da59 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -928,7 +928,7 @@ int uv_read_start(uv_stream_t* stream, if (stream->flags & UV_HANDLE_CLOSING) return UV_EINVAL; - if (stream->flags & UV_HANDLE_READING) + if (stream->read_cb != NULL) return UV_EALREADY; if (!(stream->flags & UV_HANDLE_READABLE)) From 2ad029bfbd59b34d60ffa2cf9268dc83b2177605 Mon Sep 17 00:00:00 2001 From: Edy Silva Date: Mon, 9 Mar 2026 11:40:59 -0300 Subject: [PATCH 2/4] unix: null read_cb before invoking EOF callback --- src/unix/stream.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/unix/stream.c b/src/unix/stream.c index 8bd241f47..e493e1881 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -929,11 +929,16 @@ static void uv__write_callbacks(uv_stream_t* stream) { static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) { + uv_read_cb read_cb; + stream->flags |= UV_HANDLE_READ_EOF; uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); uv__handle_stop(stream); uv__stream_osx_interrupt_select(stream); - stream->read_cb(stream, UV_EOF, buf); + read_cb = stream->read_cb; + stream->read_cb = NULL; + stream->alloc_cb = NULL; + read_cb(stream, UV_EOF, buf); } From 12ebe23eb23f90930d7b19123ecf27eb66962549 Mon Sep 17 00:00:00 2001 From: Edy Silva Date: Tue, 10 Mar 2026 15:45:51 -0300 Subject: [PATCH 3/4] revet changes to uv-common --- src/uv-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uv-common.c b/src/uv-common.c index 86d79da59..e5a763290 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -928,7 +928,7 @@ int uv_read_start(uv_stream_t* stream, if (stream->flags & UV_HANDLE_CLOSING) return UV_EINVAL; - if (stream->read_cb != NULL) + if (stream->flags & UV_HANDLE_READING) return UV_EALREADY; if (!(stream->flags & UV_HANDLE_READABLE)) From 877bf9ee907625ad48b961f62b3a96bdf31a4fb5 Mon Sep 17 00:00:00 2001 From: Edy Silva Date: Tue, 10 Mar 2026 21:09:44 -0300 Subject: [PATCH 4/4] assert NULL read_cb in unix only --- src/uv-common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/uv-common.c b/src/uv-common.c index e5a763290..6447c124f 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -928,8 +928,13 @@ int uv_read_start(uv_stream_t* stream, if (stream->flags & UV_HANDLE_CLOSING) return UV_EINVAL; - if (stream->flags & UV_HANDLE_READING) +#ifdef _WIN32 + if (stream->flags & UV_HANDLE_READING) + return UV_EALREADY; +#else + if (stream->read_cb != NULL) return UV_EALREADY; +#endif if (!(stream->flags & UV_HANDLE_READABLE)) return UV_ENOTCONN;