php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #21330 stream_select is not consistant with socket_select
Submitted: 2003-01-02 01:27 UTC Modified: 2003-01-02 16:18 UTC
Votes:2
Avg. Score:3.0 ± 1.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: chip at cyan dot com Assigned:
Status: Not a bug Package: Sockets related
PHP Version: 4.3.0 OS: FreeBSD 4.7-stable
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: chip at cyan dot com
New email:
PHP Version: OS:

 

 [2003-01-02 01:27 UTC] chip at cyan dot com
All references to stream_select (an otherwise un-documented function) say that it is the same as socket_select.

With socket_select setting the 4th parameter (the timeout in seconds) to 0 would normaly make it wait for a change in the sockets forever(no timeout).

However with stream_select, if you set the 4th parameter to 0,  it does not wait at all, instead returning right away.  To create the desired effect you must set it equal to NULL.
Workaround:
Set the 4th parameter (seconds) to NULL

To Fix:
change line line 789 in 
/ext/standard/file.c( as included in php 4.3.0 /* $Id: file.c,v 1.279.2.4 2002/12/26 22:36:21 wez Exp $ */) from:

        if (sec != NULL) {

to:

        if (sec != NULL && sec != 0) {

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-01-02 07:08 UTC] wez@php.net
stream_select() treats a 0 timeout as the regular select() system call does; it means do not block if no events are pending (timeout immediately).

A NULL value is the traditional "wait for eternity" behaviour that you have described, and so it sounds like socket_select() is actually the broken function.
 [2003-01-02 07:15 UTC] wez@php.net
Err, can you check that again?
The code for both stream_select() and socket_select() appear to treat 0 in the same way (timeout immediately).
 [2003-01-02 07:47 UTC] nicos@php.net
Assigned to nicos and Wez.
 [2003-01-02 07:48 UTC] nicos@php.net
Assigned to nicos and Wez.

_Really_ now
 [2003-01-02 12:15 UTC] wez@php.net
Please try this script; it works just fine here.

The expected output is this:
resource(4) of type (Socket)
Testing timeout of 0 seconds
Timeout after 0 seconds, n is 0
OK!

Testing timeout of 5 seconds
Timeout after 5 seconds, n is 0
OK!

Please allow a good 10 seconds for this last part; it should never
return; after more than 10 seconds, stop the script by pressing CTRL-C
Testing timeout of infinite seconds


<?php

function timeout_test($s, $duration)
{
    $t1 = time();
    printf("Testing timeout of %s seconds\n", $duration === null ? "infinite" : $duration);

    $n = socket_select($r = array($s), $w = null, $e = null, $duration);
    $t2 = time();

    $actual = $t2 - $t1;
    
    printf("Timeout after %d seconds, n is %d\n", $actual, $n);

    if ($actual != $duration) {
        echo "---> FAILED? (although a small difference is allowed!)\n";
    } else {
        echo "OK!\n";
    }  
    echo "\n";
    
}

$s = socket_create(AF_INET, SOCK_STREAM, 0);
var_dump($s);

timeout_test($s, 0);
timeout_test($s, 5);

echo "Please allow a good 10 seconds for this last part; it should never\n";
echo "return; after more than 10 seconds, stop the script by pressing CTRL-C\n";

timeout_test($s, null);

?>

 [2003-01-02 16:13 UTC] nicos@php.net
Please use that script and not the previous one:

<?php

function timeout_test($s, $duration)
{
    $t1 = time();
    printf("Testing timeout of %s seconds\n", $duration === null ?
"infinite" : $duration);

    $n = socket_select($r = array($s), $w = null, $e = null,
$duration);
    $t2 = time();

    $actual = $t2 - $t1;

    printf("Timeout after %d seconds, n is %d\n", $actual, $n);

    if ($actual != $duration) {
        echo "---> FAILED? (although a small difference is
allowed!)\n";
    } else {
        echo "OK!\n";
    }
    echo "\n";

}

$s = socket_create(AF_INET, SOCK_STREAM, 0);
var_dump($s);
socket_bind($s, "localhost", 14450);
socket_listen($s);

timeout_test($s, 0);
timeout_test($s, 5);
timeout_test($s, null);

?>

 [2003-01-02 16:18 UTC] nicos@php.net
Okay after some feedbacks, it looks that it is bogus. You seem to think that 0 is NULL but it's not. Actually if you give 0 to socket_select it will wait 0 second. Only NULL will be socket_select infinite. So it looks you have to use NULL directly and not 0. Please read http://www.php.net/manual/en/function.socket-select.php it's well explained there: 
" The tv_sec and tv_usec  together form the timeout parameter. The timeout is an upper bound on the amount of time elapsed before socket_select() return. tv_sec may be zero , causing socket_select() to return immediately. This is useful for polling. If tv_sec is NULL (no timeout), socket_select() can block indefinitely. "


Thank you for your report.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Jan 15 12:01:29 2025 UTC