Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-16889: stream_select() timeout useless for pipes on Windows #16917

Open
wants to merge 4 commits into
base: PHP-8.2
Choose a base branch
from

Conversation

cmb69
Copy link
Member

@cmb69 cmb69 commented Nov 24, 2024

Pipes are blocking on Windows, but php_select() always returns them as ready for read/write. This renders the stream_select() timeout useless, what can cause a following read to block for a very long time.

While there is no general fix (and least not within reach for a stable version), we can at least cater to the important case of read pipes by peeking the pipe to check whether data is available. If there is none, we do not add the handle to the read set.

Pipes are blocking on Windows, but `php_select()` always returns them
as ready for read/write.  This renders the `stream_select()` timeout
useless, what can cause a following read to block for a very long time.

While there is no general fix (and least not within reach for a stable
version), we can at least cater to the important case of read pipes by
peeking the pipe to check whether data is available.  If there is none,
we do not add the handle to the read set.
@cmb69 cmb69 linked an issue Nov 24, 2024 that may be closed by this pull request
The test assumes that at least the stdin and stdout pipes are always
selected as readable, and that the select call will not change their
order.  We're being more defensive now.
@cmb69
Copy link
Member Author

cmb69 commented Nov 24, 2024

stream_select($read, $write, $except, null, 0);

This now waits indefinitely on Windows, what it is supposed to do according to man 2 select, since we're passing timeout=NULL in this case. Don't know why it apparently doesn't do that on other platforms.

PS: ah, because reading files won't block there.

PPS: it's not supposed to block indefinitely; we must not call PeekNamedPipe() on file handles, though.

* bug60602.phpt has the same issue as bug64770.phpt (copy&paste)
* bug49936_win32.phpt should suppress the warnings[1], or be dropped
  altogether[2]

[1] <php@c884d37>
[2] <php@2c6b85f>
`FILE_TYPE_PIPE` will also be returned for sockets, but these have been
filtered out already.
@cmb69
Copy link
Member Author

cmb69 commented Nov 24, 2024

Given that I had to patch a couple of test cases, it might make sense to only apply this to master. However, in https://bugs.php.net/bug.php?id=51800#1561307300, @nicolas-grekas wrote:

A working stream_select() on a pipe would allow writing libs that don't hit the issue. The current ways are hideous (piping to a temporary file...)

@cmb69 cmb69 marked this pull request as ready for review November 24, 2024 19:35
@cmb69 cmb69 requested a review from bukka as a code owner November 24, 2024 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

stream_select() timeout useless for pipes on Windows
1 participant