From 6999994def3b05ae1ed5edf594642d975e3bed05 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 7 Jul 2022 15:24:35 -0400 Subject: [PATCH] unix,stream: optimize uv_shutdown() codepath (#3646) Once the write queue is empty, we can fire the event immediately, without needing a lot of syscalls and then waiting for the kernel to feed us the event on the next tick. This also makes it more similar to how it would behave if there was a write still in the queue also, which we dispatch later in the same event loop iteration, then drain. --- src/unix/stream.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/unix/stream.c b/src/unix/stream.c index 74430caa..b0887880 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -1232,7 +1232,8 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) { assert(uv__stream_fd(stream) >= 0); - /* Initialize request */ + /* Initialize request. The `shutdown(2)` call will always be deferred until + * `uv__drain`, just before the callback is run. */ uv__req_init(stream->loop, req, UV_SHUTDOWN); req->handle = stream; req->cb = cb; @@ -1240,8 +1241,8 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) { stream->flags |= UV_HANDLE_SHUTTING; stream->flags &= ~UV_HANDLE_WRITABLE; - uv__io_start(stream->loop, &stream->io_watcher, POLLOUT); - uv__stream_osx_interrupt_select(stream); + if (QUEUE_EMPTY(&stream->write_queue)) + uv__io_feed(stream->loop, &stream->io_watcher); return 0; }