[php-src] Issue #23978: PHP_STREAM_OPTION_READ_TIMEOUT is also used for socket write timeouts
| From: | matyhtf | Date: | Tue, 29 Sep 2026 02:04:52 +0000 |
| Subject: | [php-src] Issue #23978: PHP_STREAM_OPTION_READ_TIMEOUT is also used for socket write timeouts | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-252846@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/23978
Author: matyhtf
### Description
stream_set_timeout() passes PHP_STREAM_OPTION_READ_TIMEOUT to the stream
wrapper:
https://github.com/php/php-src/blob/810ac6dc4d2bb5b74f0a9ba478f4b9202f68cb10/ext/standard/streamsfuncs.c#L1494-L1499
The constant and its comment explicitly describe a read timeout:
https://github.com/php/php-src/blob/810ac6dc4d2bb5b74f0a9ba478f4b9202f68cb10/main/php_streams.h#L448-L450
However, the native socket stream stores this option in the single sock->timeout
field:
https://github.com/php/php-src/blob/810ac6dc4d2bb5b74f0a9ba478f4b9202f68cb10/main/streams/xp_socket.c#L407-L410
That timeout is used by both php_sockop_read() and php_sockop_write(). In
particular, a blocking write which encounters EAGAIN/EWOULDBLOCK waits for
POLLOUT using the same timeout:
https://github.com/php/php-src/blob/810ac6dc4d2bb5b74f0a9ba478f4b9202f68cb10/main/streams/xp_socket.c#L65-L128
This creates an ambiguity for extension and alternative stream-wrapper implementers: following the
constant name and header comment produces a read-only implementation, while matching native PHP
socket stream behavior requires applying the value to both blocking reads and blocking writes.
This ambiguity caused a real compatibility issue in Swoole's coroutine stream hook, where
stream_set_timeout() changed the read timeout but a blocked fwrite()
continued using the previous write timeout:
https://github.com/swoole/swoole-src/pull/6260
The PHP manual currently says only that the function “sets the timeout value on the stream”; it
does not document that native network/socket streams use the value for writes as well, and its
example demonstrates only a read timeout:
https://github.com/php/doc-en/blob/master/reference/stream/functions/stream-set-timeout.xml
Suggested changes:
1. Clarify the stream_set_timeout() documentation: for native network/socket streams,
the configured timeout applies to blocking reads and blocking writes.
2. Update the misleading comment in main/php_streams.h.
3. Introduce a direction-neutral internal name such as PHP_STREAM_OPTION_IO_TIMEOUT or
PHP_STREAM_OPTION_TIMEOUT, while retaining PHP_STREAM_OPTION_READ_TIMEOUT
as an alias for source compatibility, and migrate in-tree users to the clearer name.
4. Consider adding a php-src regression test covering a blocked socket-stream write after
stream_set_timeout().
No runtime behavior change is being requested here; the goal is to make the existing behavior
unambiguous and prevent downstream implementations from interpreting the option differently.