Edit report at http://bugs.php.net/bug.php?id=52602&edit=1

 ID:                 52602
 Updated by:         cataphr...@php.net
 Reported by:        g at gsxm dot net
 Summary:            fread is blocking even with the use of stream_select
 Status:             Verified
 Type:               Bug
 Package:            Sockets related
 Operating System:   Gentoo x86_64
 PHP Version:        5.2.14
 Assigned To:        cataphract
 Block user comment: N

 New Comment:

fread is not really adequate for this because of its buffering (see
stream_socket_recvfrom()).



Since you are specifying a length of 128 to fread, if you receive say, a
138 bytes long payload, the first call to fread will to read into the
stream buffer the whole data, but will only return 128 bytes. The stream
buffer remains with 10 bytes, but the socket buffer will be empty. On
the second call to fread, it will try to read into the stream buffer
again, but this time the socket buffer is empty, so it will block until
it can read another packet or until the timeout.



This appears, however, to be the desired behavior (perhaps fread could
just return what it has in the buffer if it cannot read anything
immediately, i.e., if it would otherwise block). So stream_select
implements an emulation behavior that says the stream is readable
without calling select if the there's data in the stream buffer. This is
indeed odd, because the usual semantics of select are that it a read on
a socket returned in the readfs set will not block.


Previous Comments:
------------------------------------------------------------------------
[2010-08-14 05:35:51] g at gsxm dot net

Not sure why I did not think of this before, but perhaps only the
stream-* functions works with stream_select

------------------------------------------------------------------------
[2010-08-14 03:07:41] g at gsxm dot net

Description:
------------
Using PHP CLI

Gentoo 64 bit box

PHP version 5.2.14

clean compile

Dual AMD Opteron 2212 CPU



Something is blocking in the code, it seems to be fread. I am sure this
is not the expected result.



I greatly simplified the sample I included.



I can just put the socket/stream in non-blocking mode, but I would much
prefer to use the code as I designed it. 



I have considered just using the socket functions in php or just writing
the code in C.



Once in a great while it will resume after about thirty to sixty
seconds. In non-blocking mode I have no issues. This is a php cli script
that connects to another daemon running on the same machine, I am using
this php script to parse data to place in a sql database.

Test script:
---------------
$so...@fsockopen("localhost","7777",$errno,$errstr,3);

if (!$sock)

{ 

    echo "sock error".$crlf;

}



while(true)

{

    $read=array($sock);

    $write=NULL;

    $except=NULL;

    $stat...@stream_select($read,$write,$except,1);

    if ($status===false)

    {

        echo "select error".$crlf;

        exit();

    }

    if ($status>0)

    {

        $data =  @fread($sock,128);

        echo $data;

        $out .= $data;

    }

    

    usleep(10000);

}

Expected result:
----------------
The loop should run for eternity as expected.

Actual result:
--------------
The loop is blocked, I am presuming by fread due to a failure of the
expected behavior of stream_select.


------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=52602&edit=1

Reply via email to