Skip to content

async: report a failed write on the io handle (ABI 0.26.0) - #27

Merged
EdmondDantes merged 1 commit into
true-asyncfrom
async-write-failed-state
Aug 23, 2026
Merged

async: report a failed write on the io handle (ABI 0.26.0)#27
EdmondDantes merged 1 commit into
true-asyncfrom
async-write-failed-state

Conversation

@EdmondDantes

Copy link
Copy Markdown

A write submitted without an awaiter gets no status of its own: its completion is a free_cb taking the handle and the user pointer, nothing else. The consumer was left to infer the failure from the read side — and there a peer that merely shut its write half down looks exactly like one that is gone.

ZEND_ASYNC_IO_WRITE_FAILED (bit 7, the first free one) is that report. The reactor sets it on the handle when a write completes with an error and never clears it. It says nothing about the read side, which is the point: a half-closed peer keeps reading.

Why the read side cannot stand in for it: the kernel hands so_error to whichever syscall asks first, and with a saturated outbound queue that is the write. Measured on bare sockets after an RST — write -> ECONNRESET, write -> EPIPE, read -> b'': the read behind the failing write returns a clean EOF and reports nothing.

Consumers: php-async sets the flag (true-async/php-async, branch write-failed-state-bit), and true-async/server reads it to keep a half-closed peer's response alive while still answering 499 to one that is gone (true-async/server#249). Both are guarded, so neither needs this to land first in order to build.

ABI 0.25.0 → 0.26.0: additive, no signature or layout change.

A write submitted without an awaiter gets no status of its own: its completion
is a free_cb that takes the handle and the user pointer, nothing else. The
consumer was left to infer the failure from the read side, where a peer that
merely shut its write half down looks exactly like one that is gone.
ZEND_ASYNC_IO_WRITE_FAILED is that report. The reactor sets it on the handle
when a write completes with an error and never clears it, so a consumer can
tell "this connection can no longer be written to" from "this peer has stopped
sending". It says nothing about the read side.
Sign up for freeto 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.

1 participant

@EdmondDantes