-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
stream_socket_accept() timeout sometimes doesn't work? #13220
Comments
I have been playing with this and did a bit of debugging. This is expected behavior. The reason is that you are essential using pre-forking (forking between listen and accept). That means that you have two processes to accept connection in parallel. The part that you might not know that the timeout is done using poll (checking if listened socket is readable - meaning there is connection to accept available) before doing the actual accept. The issue that you see is that both process polling at the same time on the same socket. If there is a connection available, it will unblock both of them, but only one of them will accept the connection and the other one will be blocked. But this time it will be blocked on the actual accept that does not have any timeout. It will get unblocked when there is a new connection but the other process might get released by poll and then get blocked on accept again (that's why you see it swapped). This might not be always the case and I saw that sometimes it just release accept but does not release poll because before it gets that info, the connection is already accepted by other process. Hope it makes sense. If you really wanted to make sure that the timeout is always applied, then use non blocking socket or use some sort of IPC (e.g. using pipes). In any case this is not a PHP issue but more issue with your code. |
Thank you for your reply and help! |
Yes that's what I described above. It's because there's some sort of race condition between polling and accepting so it get stuck on accept where it is not possible to set timeout. This cannot be handled without external synchronization which you need to do in your application or use non blocking socket as I mentioned above. |
I will actually re-open this as it might be possible to get around this by making accept non blocking (changing socket to non blocking and then back to blocking if it was blocking). We do similar thing in OpenSSL so this could be applied here as well. |
Description
The following simple client-server socket code:
Resulted in this output:
But I expected this output instead:
The problem:
PHP Version
PHP 8.3+
Operating System
Rocky Linux 9.3 (6.6.10-1.el9)
The text was updated successfully, but these errors were encountered: