ID: 17083 Updated by: [EMAIL PROTECTED] Reported By: [EMAIL PROTECTED] -Status: Open +Status: Closed Bug Type: Sockets related Operating System: RH 7.1 PHP Version: 4.2.0 New Comment:
This is a known issue that will be fixed in 4.2.1, if you need to work around it use the latest snapshot. -Jason Previous Comments: ------------------------------------------------------------------------ [2002-05-07 18:51:55] [EMAIL PROTECTED] The script below listens on 10 ports from 26001 to 26010. On return from socket_select, all sockets have stopped listening except the one on which there is action, plus 26010. This is wrong. All 10 sockets should still be listening. strace reveals that close() is being called on the other sockets. I suspect this is because the garbage collector does not detect that the $listen_sockets and $r arrays are different, because for efficiency it does not actually make a copy until one of the arrays is modified. When the old value of $r is discarded to make way for the results from select(), the engine detects that the use counts on most of the socket resource objects have gone to zero. The two exceptions are the socket that woke up select(), and the 10th created socket still stored in $sock. To test this, I added $sockcopy as yet another copy of all the sockets. The problem persisted. Next, I added an additional junk value to $sockcopy to force the engine to make a separate internal copy, instead of keeping just a reference. That fixed the problem. ...Tom Robinson #!/usr/local/bin/php -q <?php ob_implicit_flush (); for ($i = 1; $i <= 10 ; ++$i){ ($sock = socket_create(AF_INET, SOCK_STREAM, 0)) or die ("socket $i"); socket_setopt($sock, SOL_SOCKET, SO_REUSEADDR, 1); ($b= socket_bind($sock, '0.0.0.0', 26000+$i)) or die("bind $i"); ($l= socket_listen($sock, 4)) or die ("listen $i"); socket_set_nonblock($sock); $listen_sockets[$i] = $sock; } $sockcopy = $listen_sockets; // for speed, engine makes just a reference until one of them changes //$sockcopy["end"] = "more stuff"; // so engine makes a copy right now $r = $listen_sockets; echo ' To see the 10 listening sockets: netstat -a | grep 260 Then connect to one of the ports: telnet localhost 26005 This will cause select to return. Repeat the netstat - only 2 sockets listening now! Then repeat the procedure, un-commenting the //$sockcopy["end"] line. Waiting on select()...'; $x = socket_select($r, $w = null, $e = null, null); echo "\n"; echo "select r: ", count($r), " w: ", count($w), " e: ", count($e), "\n"; echo "Sleep 30 s before exiting..."; sleep(30); echo "\n"; exit(); ?> ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=17083&edit=1