Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- **A write submitted without an awaiter reports its failure on the handle.** `io_pipe_write_cb` and `io_pipe_writev_cb` know the libuv status, but on that path the request is freed here and its `free_cb` takes no status, so the error object was built and released without anyone seeing it — a consumer could only infer the failure from the read side, where a peer that shut its write half down looks exactly like one that is gone. Both callbacks now set `ZEND_ASYNC_IO_WRITE_FAILED` on the io handle, which the reactor never clears. Needs php-src carrying that flag (TrueAsync ABI 0.26.0); against an older one the report is compiled out.
- **A write submitted without an awaiter reports its failure on the handle.** `io_pipe_write_cb` and `io_pipe_writev_cb` know the libuv status, but on that path the request is freed here and its `free_cb` takes no status, so the error object was built and released without anyone seeing it — a consumer could only infer the failure from the read side, where a peer that shut its write half down looks exactly like one that is gone. Both callbacks now set `ZEND_ASYNC_IO_WRITE_FAILED` on the io handle, which the reactor never clears. Needs php-src carrying that flag (TrueAsync ABI 0.26.0).

### Fixed

Expand Down
7 changes: 1 addition & 6 deletions libuv_reactor.c
Original file line number Diff line number Diff line change
Expand Up @@ -4926,13 +4926,10 @@ static void io_pipe_write_cb(uv_write_t *write_request, int status)
async_new_exception(async_ce_input_output_exception, "Pipe write error: %s", uv_strerror(status));

/* The handle carries the verdict because the request may not: a
* fire-and-forget write is freed here, and its free_cb takes no status.
* Guarded because php-src carries the flag only from ABI 0.26.0. */
#ifdef ZEND_ASYNC_IO_WRITE_FAILED
* fire-and-forget write is freed here, and its free_cb takes no status. */
if (io != NULL) {
io->base.state |= ZEND_ASYNC_IO_WRITE_FAILED;
}
#endif
}

req->base.completed = true;
Expand Down Expand Up @@ -5005,11 +5002,9 @@ static void io_pipe_writev_cb(uv_write_t *write_request, int status)

/* See io_pipe_write_cb: the handle keeps the verdict for a caller whose
* completion carries none. */
#ifdef ZEND_ASYNC_IO_WRITE_FAILED
if (req->io != NULL) {
req->io->base.state |= ZEND_ASYNC_IO_WRITE_FAILED;
}
#endif
}
req->base.completed = true;

Expand Down
Loading