# socket_select() problem

- Thread: https://externals.io/message/39642
- Original archive: https://news-web.php.net/php.internals/39642
- Started by Ian Eure on 2008-08-04T20:43:28+00:00
- Messages: 2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #39642 — Ian Eure — 2008-08-04T20:43:28+00:00

URL: https://externals.io/message/39642#39642

Hi, I have a problem with `socket_select()`. I hope someone here can  
point me in the right direction, because I'm stumped.

Basically, I'm getting this error:

Warning: `socket_select()` [function.socket-select]: no resource arrays  
were passed to select in Net/Gearman/Client.php on line 197

This is using the Net_Gearman PEAR package to submit a Gearman job.  
The job is submitted and runs to completion; this message is displayed  
by the caller.

The relevant code is here:
http://code.google.com/p/netgearman/source/browse/trunk/Net/Gearman/Client.php#197

             $write  = null;
             $except = null;
             $read   = $this->conn;
             socket_select($read, $write, $except, 10);

If I add var_dump($read) on the line above `socket_select()`, I get:
array(2) {
   [0]=>
   resource(141) of type (Socket)
   [1]=>
   resource(142) of type (Socket)
}

The error message appears to be spurious. This is where the socket is  
created:

             $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
             @socket_connect($socket, $host, $port);
             $errorCode = socket_last_error($socket);

             socket_set_nonblock($socket);
             socket_set_option($socket, SOL_TCP, 1, 1);

I removed the @, and there were no errors being hidden. I resorted to  
examining the socket extension code, and these are my findings:

 `socket_select()` calls php_sock_array_to_fd_set() on $read / $write /  
$except:
http://cvs.php.net/viewvc.cgi/php-src/ext/sockets/sockets.c?revision=1.199&view=markup#l788

If the result of all three of those operations is zero, the error  
message is displayed.

php_sock_array_to_fd_set() checks to see if the argument it got is an  
array:
http://cvs.php.net/viewvc.cgi/php-src/ext/sockets/sockets.c?revision=1.199&view=markup#l710
If not, it returns zero.

php_sock_array_to_fd_set() calls zend_fetch_resource():
http://cvs.php.net/viewvc.cgi/php-src/ext/sockets/sockets.c?revision=1.199&view=markup#l716

If that returns zero for every element in the array,  
php_sock_array_to_fd_set() also returns zero.

Since I'm dumping $read directly before the `socket_select()` call, it  
seems that the zend_fetch_resource() call is what's failing.

I wrote a simple testcase that submits a single job to Gearman. If I  
run it under Apache2, I get the `socket_select()` warning. If I run it  
from the CLI, I don't. I'm also pointing the CLI at the Apache2  
php.ini file. At this point, I don't know how to track this any  
further. If I was getting the same error on the CLI, I could trace it  
with gdb. I don't know how I'd go about doing something like that for  
an Apache extension.

I'm running PHP 5.2.0 under Debian Etch, installed from the vanilla  
Debian packages (5.2.0-8+etch1). I have APC and Memcache extensions  
installed from PECL. I disabled both, and there was no change in what  
I'm seeing. I also emailed everyone listed in socket.c, but I got no  
response.

I'm at a loss. Where do I go from here?

  - Ian

---

## #39647 — Andrei Zmievski — 2008-08-05T00:50:05+00:00

URL: https://externals.io/message/39642#39647 · In reply to: #39642

Ian Eure wrote:
> I wrote a simple testcase that submits a single job to Gearman. If I run 
> it under Apache2, I get the `socket_select()` warning. If I run it from 
> the CLI, I don't. I'm also pointing the CLI at the Apache2 php.ini file. 
> At this point, I don't know how to track this any further. If I was 
> getting the same error on the CLI, I could trace it with gdb. I don't 
> know how I'd go about doing something like that for an Apache extension.

A really quick answer to this part:

If you want to trace this with gdb run Apache2, stop apache processes, 
then run apache under gdb like this:

% sudo gdb apache2
 > run -X

You can set the breakpoint before "run -X" or after it finishes loading 
by stopping it with Ctrl-C, setting breakpoint, and cont'inuing. -X 
ensures that it runs only a single process.

-Andrei
