Bug #20745 [Com]: socket_accept() in blocking mode doesn't handle signal interrupts

From: Date: Tue, 14 Dec 2010 16:33:43 +0000
Subject: Bug #20745 [Com]: socket_accept() in blocking mode doesn't handle signal interrupts
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-157000@lists.php.net to get a copy of this message
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 <?php define ( 'BIND_PORT', 3333 ); /* Signal Handler */ function signalHandler( $sig ) { switch ( $sig ) { case SIGTERM : exit( 0 ); break; case SIGCHLD : pcntl_waitpid(-1,$status,WNOHANG); break; } } print "My PID is ".posix_getpid()."\n"; declare ( ticks = 1 ); pcntl_signal( SIGTERM, 'signalHandler' ); pcntl_signal( SIGCHLD, 'signalHandler' ); // infinite execution time set_time_limit( 0 ); // Socket creation $sock = socket_create ( AF_INET, SOCK_STREAM, SOL_TCP ); // Bind sur le port BIND_PORT if ( !socket_bind( $sock, '0.0.0.0', BIND_PORT ) ) { print "Unable to bind to port " . BIND_PORT . " !\n"; exit( 1 ); } // Listening up to 16 buffets socket_listen ( $sock, 16 ); // Infinite loop while ( true ) { // Wait for incoming connections, hangs signal handling $subsock = socket_accept ( $sock ); // Connection received, forking sub-process $subPid = pcntl_fork(); if ( $subPid === 0 ) { // Get remote informations socket_getpeername( $subsock , $remoteAddr , $remotePort ); socket_write( $subsock, 'Simple Socket Server accepting commands from ' . $remoteAddr . "\n" ); // Whe are in interactive mode while ( true ) { $received = socket_read ( $subsock, 65536, PHP_NORMAL_READ ); // Clean shutdown if ( !$received ) { socket_shutdown( $subsock, 2 ); socket_close( $subsock ); exit( 0 ); } // Cleaning entry $received = trim( $received ); if ( $received ) { // two commands : HELLO and QUIT switch ( $received ) { case 'HELLO': socket_write( $subsock, 'HELLO ' . $remoteAddr . "\n" ); break; case 'QUIT': // (shutdown) socket_write( $subsock, 'BYE' . "\n" ); socket_shutdown( $subsock, 2 ); socket_close( $subsock ); exit( 0 ); break; default : socket_write( $subsock, 'Unknown command...' . "\n" ); } } } } } // while ?> ------------------------------------------------------------------ Commands : [Shell1]$ ./script.php My PID is 18135 [Shell2]$ kill 18135 <Happens nothing on Shell1...> [Shell2]$ telnet localhost 3333 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

« previous php.bugs (#157000) next »