Skip to content

Pause a stopped listen event instead of accepting through it (#305) - #306

Merged
EdmondDantes merged 1 commit into
mainfrom
listen-pause
Sep 30, 2026
Merged

EdmondDantes merged 1 commit into
mainfrom
listen-pause

Conversation

@EdmondDantes

Copy link
Copy Markdown
Contributor

Fixes #305. libuv cannot undo uv_listen, so stop() now pauses: the connection callback leaves the connection unaccepted, and libuv stops watching the socket (Unix) or posts no new AcceptEx (Windows). The first start() runs uv_listen; a later one unpauses and delivers the held connection from a uv_idle_t on the next tick. The delivery stops if a callback pauses or closes the listener. The first stop() switches a Windows TCP listener to single accept, so a listener that is never stopped keeps libuv's default. A failed uv_accept on Unix re-arms the watcher with uv_listen, since libuv restarts it only after a successful accept.

Reviewed before code by a Critic and a Sage (rejected: a uv_poll accept loop), and on the diff by a Critic; its four findings are addressed in this commit.

Evidence:

  • sapi/asynctest/tests/test_listen_pause.c (true-async/php-src PR on branch listen-pause-test): 5 of 5 cases red on main, green here, 3 of 3 runs.
  • true-async-server h1/062, h1/063, h1/064: 503 on main, 10 of 10 green here; the server's full phpt suite, 516 of 516 green (25 skipped).
  • php-async phpt: 1214 of 1220; the 6 failures fail identically on main on this machine. They include php-src helpers through ../../../../, which misses when ext/async is a symlink.

Not measured: the accept rate of a Windows listener after its first pause.

@codecov

codecov Bot commented Sep 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@EdmondDantes

Copy link
Copy Markdown
Contributor Author

ASan run of sapi/asynctest/tests/test_listen_pause.c against this branch (minimal ZTS debug build with --enable-address-sanitizer, ASAN_OPTIONS=detect_leaks=1 USE_ZEND_ALLOC=0): 5 of 5 cases, 3 of 3 runs, no AddressSanitizer or LeakSanitizer report; test-listen_uaf and test-timer_overflow clean as well. Known-answer check: with the pefree in listen_close_cb removed, LeakSanitizer reports the 528-byte listen event from listen_on_free_port.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stop() on a listen event does not stop accepting

1 participant