/** * Wait for activity on one of several sockets. * * @param list List of sockets expected to become readable. * @param list List of sockets expected to become writable. * @param float Timeout, in seconds. * @return void */ public static function waitForSockets(array $read_list, array $write_list, $timeout = 1) { if (!self::$handlerInstalled) { // If we're spawning child processes, we need to install a signal handler // here to catch cases like execing '(sleep 60 &) &' where the child // exits but a socket is kept open. But we don't actually need to do // anything because the SIGCHLD will interrupt the stream_select(), as // long as we have a handler registered. if (function_exists('pcntl_signal')) { if (!pcntl_signal(SIGCHLD, array('Future', 'handleSIGCHLD'))) { throw new Exception('Failed to install signal handler!'); } } self::$handlerInstalled = true; } $timeout_sec = (int) $timeout; $timeout_usec = (int) (1000000 * ($timeout - $timeout_sec)); $exceptfds = array(); $ok = @stream_select($read_list, $write_list, $exceptfds, $timeout, $timeout_usec); if ($ok === false) { // Hopefully, means we received a SIGCHLD. In the worst case, we degrade // to a busy wait. } }