From 7bccb562e415030050cfbd1e69eeefd69ce57aca Mon Sep 17 00:00:00 2001 From: Santiago Gimeno Date: Wed, 3 Aug 2022 21:24:32 +0200 Subject: [PATCH] unix,win: remove UV_HANDLE_SHUTTING flag (#3705) Replace it with a `uv__is_stream_shutting()` macro that checks the `shutdown_req` field. It partially fixes: https://github.com/libuv/libuv/issues/3663. --- src/unix/stream.c | 6 ++---- src/unix/tcp.c | 2 +- src/uv-common.h | 9 ++++++++- src/win/pipe.c | 7 +++---- src/win/stream.c | 3 +-- src/win/tcp.c | 5 ++--- src/win/tty.c | 11 +++++------ 7 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/unix/stream.c b/src/unix/stream.c index 72d273f0..95ca92d5 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -623,7 +623,7 @@ static void uv__drain(uv_stream_t* stream) { uv__stream_osx_interrupt_select(stream); } - if (!(stream->flags & UV_HANDLE_SHUTTING)) + if (!uv__is_stream_shutting(stream)) return; req = stream->shutdown_req; @@ -632,7 +632,6 @@ static void uv__drain(uv_stream_t* stream) { if ((stream->flags & UV_HANDLE_CLOSING) || !(stream->flags & UV_HANDLE_SHUT)) { stream->shutdown_req = NULL; - stream->flags &= ~UV_HANDLE_SHUTTING; uv__req_unregister(stream->loop, req); err = 0; @@ -1183,7 +1182,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) { if (!(stream->flags & UV_HANDLE_WRITABLE) || stream->flags & UV_HANDLE_SHUT || - stream->flags & UV_HANDLE_SHUTTING || + uv__is_stream_shutting(stream) || uv__is_closing(stream)) { return UV_ENOTCONN; } @@ -1196,7 +1195,6 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) { req->handle = stream; req->cb = cb; stream->shutdown_req = req; - stream->flags |= UV_HANDLE_SHUTTING; stream->flags &= ~UV_HANDLE_WRITABLE; if (QUEUE_EMPTY(&stream->write_queue)) diff --git a/src/unix/tcp.c b/src/unix/tcp.c index 81dfa620..881f392b 100644 --- a/src/unix/tcp.c +++ b/src/unix/tcp.c @@ -317,7 +317,7 @@ int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) { struct linger l = { 1, 0 }; /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */ - if (handle->flags & UV_HANDLE_SHUTTING) + if (uv__is_stream_shutting(handle)) return UV_EINVAL; fd = uv__stream_fd(handle); diff --git a/src/uv-common.h b/src/uv-common.h index 38be9c71..bbfaaf70 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -78,7 +78,6 @@ enum { /* Used by streams. */ UV_HANDLE_LISTENING = 0x00000040, UV_HANDLE_CONNECTION = 0x00000080, - UV_HANDLE_SHUTTING = 0x00000100, UV_HANDLE_SHUT = 0x00000200, UV_HANDLE_READ_PARTIAL = 0x00000400, UV_HANDLE_READ_EOF = 0x00000800, @@ -258,6 +257,14 @@ void uv__threadpool_cleanup(void); #define uv__is_closing(h) \ (((h)->flags & (UV_HANDLE_CLOSING | UV_HANDLE_CLOSED)) != 0) +#if defined(_WIN32) +# define uv__is_stream_shutting(h) \ + (h->stream.conn.shutdown_req != NULL) +#else +# define uv__is_stream_shutting(h) \ + (h->shutdown_req != NULL) +#endif + #define uv__handle_start(h) \ do { \ if (((h)->flags & UV_HANDLE_ACTIVE) != 0) break; \ diff --git a/src/win/pipe.c b/src/win/pipe.c index 99846181..bf605b10 100644 --- a/src/win/pipe.c +++ b/src/win/pipe.c @@ -2069,9 +2069,9 @@ void uv__process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, uv__queue_non_overlapped_write(handle); } - if (handle->stream.conn.write_reqs_pending == 0) - if (handle->flags & UV_HANDLE_SHUTTING) - uv__pipe_shutdown(loop, handle, handle->stream.conn.shutdown_req); + if (handle->stream.conn.write_reqs_pending == 0 && + uv__is_stream_shutting(handle)) + uv__pipe_shutdown(loop, handle, handle->stream.conn.shutdown_req); DECREASE_PENDING_REQ_COUNT(handle); } @@ -2149,7 +2149,6 @@ void uv__process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle, /* Clear the shutdown_req field so we don't go here again. */ handle->stream.conn.shutdown_req = NULL; - handle->flags &= ~UV_HANDLE_SHUTTING; UNREGISTER_HANDLE_REQ(loop, handle, req); if (handle->flags & UV_HANDLE_CLOSING) { diff --git a/src/win/stream.c b/src/win/stream.c index 292bf588..7bf9ca38 100644 --- a/src/win/stream.c +++ b/src/win/stream.c @@ -204,7 +204,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { uv_loop_t* loop = handle->loop; if (!(handle->flags & UV_HANDLE_WRITABLE) || - handle->flags & UV_HANDLE_SHUTTING || + uv__is_stream_shutting(handle) || uv__is_closing(handle)) { return UV_ENOTCONN; } @@ -214,7 +214,6 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { req->cb = cb; handle->flags &= ~UV_HANDLE_WRITABLE; - handle->flags |= UV_HANDLE_SHUTTING; handle->stream.conn.shutdown_req = req; handle->reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); diff --git a/src/win/tcp.c b/src/win/tcp.c index b6aa4c51..f061ed76 100644 --- a/src/win/tcp.c +++ b/src/win/tcp.c @@ -214,7 +214,6 @@ void uv__process_tcp_shutdown_req(uv_loop_t* loop, uv_tcp_t* stream, uv_shutdown assert(stream->flags & UV_HANDLE_CONNECTION); stream->stream.conn.shutdown_req = NULL; - stream->flags &= ~UV_HANDLE_SHUTTING; UNREGISTER_HANDLE_REQ(loop, stream, req); err = 0; @@ -550,7 +549,7 @@ int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) { struct linger l = { 1, 0 }; /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */ - if (handle->flags & UV_HANDLE_SHUTTING) + if (uv__is_stream_shutting(handle)) return UV_EINVAL; if (0 != setsockopt(handle->socket, SOL_SOCKET, SO_LINGER, (const char*)&l, sizeof(l))) @@ -1163,7 +1162,7 @@ void uv__process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, closesocket(handle->socket); handle->socket = INVALID_SOCKET; } - if (handle->flags & UV_HANDLE_SHUTTING) + if (uv__is_stream_shutting(handle)) uv__process_tcp_shutdown_req(loop, handle, handle->stream.conn.shutdown_req); diff --git a/src/win/tty.c b/src/win/tty.c index 0462045c..c41a16ef 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -2234,11 +2234,11 @@ void uv__process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, handle->stream.conn.write_reqs_pending--; - if (handle->stream.conn.write_reqs_pending == 0) - if (handle->flags & UV_HANDLE_SHUTTING) - uv__process_tty_shutdown_req(loop, - handle, - handle->stream.conn.shutdown_req); + if (handle->stream.conn.write_reqs_pending == 0 && + uv__is_stream_shutting(handle)) + uv__process_tty_shutdown_req(loop, + handle, + handle->stream.conn.shutdown_req); DECREASE_PENDING_REQ_COUNT(handle); } @@ -2269,7 +2269,6 @@ void uv__process_tty_shutdown_req(uv_loop_t* loop, uv_tty_t* stream, uv_shutdown assert(req); stream->stream.conn.shutdown_req = NULL; - stream->flags &= ~UV_HANDLE_SHUTTING; UNREGISTER_HANDLE_REQ(loop, stream, req); /* TTY shutdown is really just a no-op */