Files
bun-src/patches/libuv/win-poll-abort-with-disconnect.patch
T
2026-08-27 21:09:14 +00:00

52 lines
2.4 KiB
Diff

--- a/src/win/poll.c
+++ b/src/win/poll.c
@@ -115,9 +115,24 @@
AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT;
} else {
if (handle->events & UV_DISCONNECT) {
- afd_poll_info->Handles[0].Events |= AFD_POLL_DISCONNECT;
+ /* A peer abort (RST) must wake a watcher that asked for disconnect
+ * even when it is not reading: AFD only reports subscribed events, so
+ * without ABORT here a reset against a write-only poll is never
+ * delivered and teardown waits forever (see the reporting hunk). */
+ afd_poll_info->Handles[0].Events |= AFD_POLL_DISCONNECT |
+ AFD_POLL_ABORT;
}
}
+ if (handle->events & UV_PRIORITIZED) {
+ /* ABORT-only subscription. A graceful FIN leaves AFD_POLL_DISCONNECT
+ * signaled forever (AFD is level-triggered), so a watcher that already
+ * consumed the FIN cannot keep DISCONNECT armed without completing
+ * instantly in a loop - yet it still needs the peer's later RST.
+ * UV_PRIORITIZED, unused on Windows, subscribes exactly that remaining
+ * signal; the reporting below surfaces it as UV_PRIORITIZED so the
+ * requested-events mask keeps it. */
+ afd_poll_info->Handles[0].Events |= AFD_POLL_ABORT;
+ }
if (handle->events & UV_WRITABLE) {
afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL;
}
@@ -168,9 +183,19 @@
if ((afd_poll_info->Handles[0].Events & (AFD_POLL_RECEIVE |
AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT)) != 0) {
events |= UV_READABLE;
- if ((afd_poll_info->Handles[0].Events & AFD_POLL_DISCONNECT) != 0) {
- events |= UV_DISCONNECT;
- }
+ }
+ if ((afd_poll_info->Handles[0].Events &
+ (AFD_POLL_DISCONNECT | AFD_POLL_ABORT)) != 0) {
+ /* Graceful FIN and abortive RST both mean the peer is gone. Report
+ * DISCONNECT for either, outside the READABLE block, so it survives
+ * the requested-events mask when only UV_DISCONNECT is armed. */
+ events |= UV_DISCONNECT;
+ }
+ if ((afd_poll_info->Handles[0].Events & AFD_POLL_ABORT) != 0) {
+ /* The ABORT-only subscription reports as UV_PRIORITIZED: a watcher
+ * armed with UV_PRIORITIZED alone has UV_DISCONNECT stripped by the
+ * requested-events mask below. */
+ events |= UV_PRIORITIZED;
}
if ((afd_poll_info->Handles[0].Events & (AFD_POLL_SEND |
AFD_POLL_CONNECT_FAIL)) != 0) {