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

Reply via email to