Bug #20745 [Com]: socket_accept() in blocking mode doesn't handle signal interrupts
Edit report at http://bugs.php.net/bug.php?id=20745&edit=1 ID: 20745 Comment by: contact at aldrik dot net Reported by:polone at townnews dot com Summary:socket_accept() in blocking mode doesn't handle signal interrupts Status: Closed Type: Bug Package:Sockets related Operating System: Linux PHP Version:4.2.3 Block user comment: N Private report: N New Comment: Could this bug be reopened ? Mapping of posix API isn't well done, the workaround introduce latency and make people loose their time. Signal are made to interrupt workflow, even on blocking situation. Previous Comments: [2008-03-06 15:25:36] polone at townnews dot com This IS a bug - all you've stated is _another_ workaround - less elegant than just setting the socket_accept() call to non-blocking and sleeping for 1 second (or you can sleep for microseconds in PHP 5) in the loop. It doesn't fix the underlying problem - which is that socket_accept() does not behave like accept(). If I issue SIGUSR1 - I should not have to set SIGALRM to 'reap' signals. Signals are suppose to interrupt blocking waits like this. I shoudn't have to make the accept() call non-blocking. At the very least - the non-standard behavior of this function (and it's caveats) should be documented. [2008-03-06 14:47:48] rose dot andrew at gmail dot com This is not a bug. socket_accept() will ignore all signals expect an alarm. I have documented how to use this method of interrupting socket_accept() here: http://andrew-rose.blogspot.com/2008/02/php-getting-signals-through-to-blocking.html [2007-11-29 01:51:59] steven dot gilberd at gmail dot com This bug still appears to exist (PHP 5.2.3-1+b1 (cli)), on at least socket_accept(). The signals just queue up until the socket receives a connection and unblocks, at which point the signals are processed as normal. I would like to request that this bug be reactivated; leaving it sitting here as 'No Feedback' isn't helping anyone. [2007-03-12 18:54:30] antoine dot bajolet at tdf dot fr Hello, The issue still exists, PHP Version => 4.4.6 System => Linux pentium2.antoine 2.6.20 #5 Sun Feb 18 16:28:17 CET 2007 i686 Build Date => Mar 6 2007 21:15:38 Complete code to reproduce error : script.php -- #!/usr/local/bin/php -- Commands : [Shell1]$ ./script.php My PID is 18135 [Shell2]$ kill 18135 [Shell2]$ telnet localhost Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Connection closed by foreign host [Shell1] : The script exits. => The signal is properly intercepted but the handler is only called when the script continues after socket_accept(). Whe are using a little more complex code when the fist process is a child of a fork itself : At this time, the only way to end it is a not very clean SIGKILL. Regards, AB [2006-05-25 19:31:39] lindsay at bitleap dot com I still see this issue with php 5.1.4. I did notice that the signal will queue up and on the next inbound connection the queued signal executes. The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/bug.php?id=20745 -- Edit this bug report at http://bugs.php.net/bug.php?id=20745&edit=1
#20745 [Com]: socket_accept() in blocking mode doesn't handle signal interrupts
ID: 20745 Comment by: steven dot gilberd at gmail dot com Reported By: polone at townnews dot com Status: No Feedback Bug Type: Sockets related Operating System: Linux PHP Version: 4.2.3 New Comment: This bug still appears to exist (PHP 5.2.3-1+b1 (cli)), on at least socket_accept(). The signals just queue up until the socket receives a connection and unblocks, at which point the signals are processed as normal. I would like to request that this bug be reactivated; leaving it sitting here as 'No Feedback' isn't helping anyone. Previous Comments: [2007-03-12 18:54:30] antoine dot bajolet at tdf dot fr Hello, The issue still exists, PHP Version => 4.4.6 System => Linux pentium2.antoine 2.6.20 #5 Sun Feb 18 16:28:17 CET 2007 i686 Build Date => Mar 6 2007 21:15:38 Complete code to reproduce error : script.php -- #!/usr/local/bin/php -- Commands : [Shell1]$ ./script.php My PID is 18135 [Shell2]$ kill 18135 [Shell2]$ telnet localhost Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Connection closed by foreign host [Shell1] : The script exits. => The signal is properly intercepted but the handler is only called when the script continues after socket_accept(). Whe are using a little more complex code when the fist process is a child of a fork itself : At this time, the only way to end it is a not very clean SIGKILL. Regards, AB [2006-05-25 19:31:39] lindsay at bitleap dot com I still see this issue with php 5.1.4. I did notice that the signal will queue up and on the next inbound connection the queued signal executes. [2006-02-09 18:55:35] flachi at gmail dot com I also have this problem with PHP 4.4.2. Is there any way to fix it ? [2003-01-02 02:50:09] piotr at t-p-l dot com I'd like to revive this bug .. as of 4.3.0 this beheaviour persists .. I even tried this define(ticks=1); approach quoted in one of the related bugs .. it didnt help .. during a call to socket_accept() as far as I can see (I've tested only with SIGTERM and SIGINT) .. those handlers never get called .. with the new feature (the 3rd param on pcntl_signal() .. set to false) .. the socket_accept() call gets interrupted, but the handler is still not called. I would say there is a need to resolve this .. right now there is no way to cleanly kill a daemon process running php unless non blocking sockets are used .. which is basicaly a waste of cpu cycles .. Please respond as to the status of this problem asap. [2002-12-15 04:05:02] [EMAIL PROTECTED] No feedback was provided. The bug is being suspended because we assume that you are no longer experiencing the problem. If this is not the case and you are able to provide the information that was requested earlier, please do so and change the status of the bug back to "Open". Thank you. The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/20745 -- Edit this bug report at http://bugs.php.net/?id=20745&edit=1
#20745 [Com]: socket_accept() in blocking mode doesn't handle signal interrupts
ID: 20745 Comment by: antoine dot bajolet at tdf dot fr Reported By: polone at townnews dot com Status: No Feedback Bug Type: Sockets related Operating System: Linux PHP Version: 4.2.3 New Comment: Hello, The issue still exists, PHP Version => 4.4.6 System => Linux pentium2.antoine 2.6.20 #5 Sun Feb 18 16:28:17 CET 2007 i686 Build Date => Mar 6 2007 21:15:38 Complete code to reproduce error : script.php -- #!/usr/local/bin/php -- Commands : [Shell1]$ ./script.php My PID is 18135 [Shell2]$ kill 18135 [Shell2]$ telnet localhost Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Connection closed by foreign host [Shell1] : The script exits. => The signal is properly intercepted but the handler is only called when the script continues after socket_accept(). Whe are using a little more complex code when the fist process is a child of a fork itself : At this time, the only way to end it is a not very clean SIGKILL. Regards, AB Previous Comments: [2006-05-25 19:31:39] lindsay at bitleap dot com I still see this issue with php 5.1.4. I did notice that the signal will queue up and on the next inbound connection the queued signal executes. [2006-02-09 18:55:35] flachi at gmail dot com I also have this problem with PHP 4.4.2. Is there any way to fix it ? [2003-01-02 02:50:09] piotr at t-p-l dot com I'd like to revive this bug .. as of 4.3.0 this beheaviour persists .. I even tried this define(ticks=1); approach quoted in one of the related bugs .. it didnt help .. during a call to socket_accept() as far as I can see (I've tested only with SIGTERM and SIGINT) .. those handlers never get called .. with the new feature (the 3rd param on pcntl_signal() .. set to false) .. the socket_accept() call gets interrupted, but the handler is still not called. I would say there is a need to resolve this .. right now there is no way to cleanly kill a daemon process running php unless non blocking sockets are used .. which is basicaly a waste of cpu cycles .. Please respond as to the status of this problem asap. [2002-12-15 04:05:02] [EMAIL PROTECTED] No feedback was provided. The bug is being suspended because we assume that you are no longer experiencing the problem. If this is not the case and you are able to provide the information that was requested earlier, please do so and change the status of the bug back to "Open". Thank you. [2002-12-01 14:31:23] [EMAIL PROTECTED] Please try using this CVS snapshot: http://snaps.php.net/php4-latest.tar.gz For Windows: http://snaps.php.net/win32/php4-win32-latest.zip The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/20745 -- Edit this bug report at http://bugs.php.net/?id=20745&edit=1
#20745 [Com]: socket_accept() in blocking mode doesn't handle signal interrupts
ID: 20745 Comment by: lindsay at bitleap dot com Reported By: polone at townnews dot com Status: No Feedback Bug Type: Sockets related Operating System: Linux PHP Version: 4.2.3 New Comment: I still see this issue with php 5.1.4. I did notice that the signal will queue up and on the next inbound connection the queued signal executes. Previous Comments: [2006-02-09 18:55:35] flachi at gmail dot com I also have this problem with PHP 4.4.2. Is there any way to fix it ? [2003-01-02 02:50:09] piotr at t-p-l dot com I'd like to revive this bug .. as of 4.3.0 this beheaviour persists .. I even tried this define(ticks=1); approach quoted in one of the related bugs .. it didnt help .. during a call to socket_accept() as far as I can see (I've tested only with SIGTERM and SIGINT) .. those handlers never get called .. with the new feature (the 3rd param on pcntl_signal() .. set to false) .. the socket_accept() call gets interrupted, but the handler is still not called. I would say there is a need to resolve this .. right now there is no way to cleanly kill a daemon process running php unless non blocking sockets are used .. which is basicaly a waste of cpu cycles .. Please respond as to the status of this problem asap. [2002-12-15 04:05:02] [EMAIL PROTECTED] No feedback was provided. The bug is being suspended because we assume that you are no longer experiencing the problem. If this is not the case and you are able to provide the information that was requested earlier, please do so and change the status of the bug back to "Open". Thank you. [2002-12-01 14:31:23] [EMAIL PROTECTED] Please try using this CVS snapshot: http://snaps.php.net/php4-latest.tar.gz For Windows: http://snaps.php.net/win32/php4-win32-latest.zip [2002-12-01 07:59:34] polone at townnews dot com The socket_accept() function doesn't appear to handle kernel level system interrupts. This is a problem because PHP scripts written to use pcntl_signal() won't be executed while socket_accept() is in blocking mode. THAT is a problem because the script can't be killed with: kill -s SIGUSR1 [pid] and can't reap zombie processes when SIGCHLD is given (not that is much of a problem on Linux, since you can use SIG_IGN). A workaround I've made is to set a socket to non-blocking mode: socket_set_nonblock($hSocket); And then use a while loop like so: while (($hClient = @socket_accept($hSocket)) === false) { // If this is a real error, we need to handle it. Unfortunately, in this // event we just die() essentially. if (!is_resource($hSocket)) { error_log(socket_strerror(socket_last_error($hSocket))); exit; } // We need to sleep for one second so that CPU isn't absorbed with this // process. This may seem clunky, but select() doesn't appear to work // correctly with accept() in PHP in blocking mode (that is EINTR does // not appear to work correctly), thus preventing signals from being // received. This, in effect, makes the process unkillable. This is the // workaround, for the moment. sleep(1); } While this works, it would be much better if it just returned when a system interrupt is given like the C-equivalent does. This works because the system can't receive messages from the kernel because it isn't blocking. -- Edit this bug report at http://bugs.php.net/?id=20745&edit=1
#20745 [Com]: socket_accept() in blocking mode doesn't handle signal interrupts
ID: 20745 Comment by: flachi at gmail dot com Reported By: polone at townnews dot com Status: No Feedback Bug Type: Sockets related Operating System: Linux PHP Version: 4.2.3 New Comment: I also have this problem with PHP 4.4.2. Is there any way to fix it ? Previous Comments: [2003-01-02 02:50:09] piotr at t-p-l dot com I'd like to revive this bug .. as of 4.3.0 this beheaviour persists .. I even tried this define(ticks=1); approach quoted in one of the related bugs .. it didnt help .. during a call to socket_accept() as far as I can see (I've tested only with SIGTERM and SIGINT) .. those handlers never get called .. with the new feature (the 3rd param on pcntl_signal() .. set to false) .. the socket_accept() call gets interrupted, but the handler is still not called. I would say there is a need to resolve this .. right now there is no way to cleanly kill a daemon process running php unless non blocking sockets are used .. which is basicaly a waste of cpu cycles .. Please respond as to the status of this problem asap. [2002-12-15 04:05:02] [EMAIL PROTECTED] No feedback was provided. The bug is being suspended because we assume that you are no longer experiencing the problem. If this is not the case and you are able to provide the information that was requested earlier, please do so and change the status of the bug back to "Open". Thank you. [2002-12-01 14:31:23] [EMAIL PROTECTED] Please try using this CVS snapshot: http://snaps.php.net/php4-latest.tar.gz For Windows: http://snaps.php.net/win32/php4-win32-latest.zip [2002-12-01 07:59:34] polone at townnews dot com The socket_accept() function doesn't appear to handle kernel level system interrupts. This is a problem because PHP scripts written to use pcntl_signal() won't be executed while socket_accept() is in blocking mode. THAT is a problem because the script can't be killed with: kill -s SIGUSR1 [pid] and can't reap zombie processes when SIGCHLD is given (not that is much of a problem on Linux, since you can use SIG_IGN). A workaround I've made is to set a socket to non-blocking mode: socket_set_nonblock($hSocket); And then use a while loop like so: while (($hClient = @socket_accept($hSocket)) === false) { // If this is a real error, we need to handle it. Unfortunately, in this // event we just die() essentially. if (!is_resource($hSocket)) { error_log(socket_strerror(socket_last_error($hSocket))); exit; } // We need to sleep for one second so that CPU isn't absorbed with this // process. This may seem clunky, but select() doesn't appear to work // correctly with accept() in PHP in blocking mode (that is EINTR does // not appear to work correctly), thus preventing signals from being // received. This, in effect, makes the process unkillable. This is the // workaround, for the moment. sleep(1); } While this works, it would be much better if it just returned when a system interrupt is given like the C-equivalent does. This works because the system can't receive messages from the kernel because it isn't blocking. -- Edit this bug report at http://bugs.php.net/?id=20745&edit=1
#20745 [Com]: socket_accept() in blocking mode doesn't handle signal interrupts
ID: 20745 Comment by: [EMAIL PROTECTED] Reported By: [EMAIL PROTECTED] Status: No Feedback Bug Type: Sockets related Operating System: Linux PHP Version: 4.2.3 New Comment: I'd like to revive this bug .. as of 4.3.0 this beheaviour persists .. I even tried this define(ticks=1); approach quoted in one of the related bugs .. it didnt help .. during a call to socket_accept() as far as I can see (I've tested only with SIGTERM and SIGINT) .. those handlers never get called .. with the new feature (the 3rd param on pcntl_signal() .. set to false) .. the socket_accept() call gets interrupted, but the handler is still not called. I would say there is a need to resolve this .. right now there is no way to cleanly kill a daemon process running php unless non blocking sockets are used .. which is basicaly a waste of cpu cycles .. Please respond as to the status of this problem asap. Previous Comments: [2002-12-15 04:05:02] [EMAIL PROTECTED] No feedback was provided. The bug is being suspended because we assume that you are no longer experiencing the problem. If this is not the case and you are able to provide the information that was requested earlier, please do so and change the status of the bug back to "Open". Thank you. [2002-12-01 14:31:23] [EMAIL PROTECTED] Please try using this CVS snapshot: http://snaps.php.net/php4-latest.tar.gz For Windows: http://snaps.php.net/win32/php4-win32-latest.zip [2002-12-01 07:59:34] [EMAIL PROTECTED] The socket_accept() function doesn't appear to handle kernel level system interrupts. This is a problem because PHP scripts written to use pcntl_signal() won't be executed while socket_accept() is in blocking mode. THAT is a problem because the script can't be killed with: kill -s SIGUSR1 [pid] and can't reap zombie processes when SIGCHLD is given (not that is much of a problem on Linux, since you can use SIG_IGN). A workaround I've made is to set a socket to non-blocking mode: socket_set_nonblock($hSocket); And then use a while loop like so: while (($hClient = @socket_accept($hSocket)) === false) { // If this is a real error, we need to handle it. Unfortunately, in this // event we just die() essentially. if (!is_resource($hSocket)) { error_log(socket_strerror(socket_last_error($hSocket))); exit; } // We need to sleep for one second so that CPU isn't absorbed with this // process. This may seem clunky, but select() doesn't appear to work // correctly with accept() in PHP in blocking mode (that is EINTR does // not appear to work correctly), thus preventing signals from being // received. This, in effect, makes the process unkillable. This is the // workaround, for the moment. sleep(1); } While this works, it would be much better if it just returned when a system interrupt is given like the C-equivalent does. This works because the system can't receive messages from the kernel because it isn't blocking. -- Edit this bug report at http://bugs.php.net/?id=20745&edit=1