mysqli_poll() - what's the third parameter for

2019-06-22 14:58发布

In the absence of any documentation beyond a function prototype I'm struggling to find what the the third parameter to the mysqli_poll() function is.

int mysqli_poll ( 
     array &$read , 
     array &$error , 
     array &$reject , 
     int $sec 
     [, int $usec ] )

Looking at the (C) source code, it appears to populate the $reject array with resources where...

CONN_GET_STATE((*p)->data) <= CONN_READY 
   || CONN_GET_STATE((*p)->data) == CONN_QUIT_SENT

Does this mean that the connection to the server is shutting down / shutdown?

Something else?

Should it be pre-poplulated with the resources to check for disconnection? Or will they be added automatically from $read and $error?

3条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-06-22 15:15

I built a test rig:

$l1 = mysqli_connect();
$l2 = mysqli_connect();
$l3 = mysqli_connect();

$s1 = "SELECT CURTIME()";
$s2 = "SELECT * FROM";   // will error #1064
$s3 = "SELECT SLEEP(10), CURTIME()";

mysqli_query($l1, $s1, MYSQLI_ASYNC);
mysqli_query($l2, $s2, MYSQLI_ASYNC);
mysqli_query($l3, $s3, MYSQLI_ASYNC);

$started=time();

for ($x=0; $x<5; $x++) {
        $ready=$reject=$errors = array($l1, $l2, $l3);
        print "\niteration $x at t+" . (time()-$started) . "\n";
        mysqli_poll($ready, $errors, $reject, 3);
        print "ready = " . count($ready) . "\n";
        foreach($ready as $r) {
           $c=mysqli_reap_async_query($r);
           print "err=" . mysqli_error($r) . " cnt=" . count($c) . "\n";
        };
        print "errors = " . count($errors) . "\n";
        print "reject = " . count($reject) . "\n";
        sleep(4);
 }

Results (annotations prefixed with //):

iteration 0 at t+0
ready = 1              // appears to be SELECT CURTIME()
err= cnt=1
errors = 0
reject = 0

iteration 1 at t+4
ready = 1              // appears to be SELECT * FROM
err=You have an error in your SQL syntax; check the manual that corresponds 
  to your MySQL server version for the right syntax to use near '' at line 
  1 cnt=1
errors = 0
reject = 1             // appears to be SELECT CURTIME() (results reaped)

iteration 2 at t+8
ready = 1              // appears to be SELECT SLEEP(10) despite 8 seconds elapsed
err= cnt=1
errors = 0
reject = 2             // appears to be SELECT CURTIME() + SELECT * FROM

iteration 3 at t+14
ready = 0
errors = 0
reject = 3

iteration 4 at t+21
ready = 0
errors = 0
reject = 3

i.e. $reject is getting populated with links where the results have been reaped, NOT links which are not yet ready to poll.

Trying with with an invalid connection, the value is removed from all arrays (not added to $reject),

查看更多
Emotional °昔
3楼-- · 2019-06-22 15:16

I believe that's where the rejected threads end up.

See this example: https://svn.osgeo.org/mapguide/sandbox/rfc94/Oem/php/ext/mysqli/tests/mysqli_poll.phpt

查看更多
乱世女痞
4楼-- · 2019-06-22 15:17

The arrays are bound to the select() system call.

As you see here: http://lxr.php.net/xref/PHP_5_5/ext/mysqlnd/mysqlnd.c#1384

So, yes, according to select(2) man documentation:

Select() examines the I/O descriptor sets whose addresses are passed in readfds, writefds, and errorfds to see if some of their descriptors are ready for reading, are ready for writing, or have an exceptional condition pending, respectively.

(writefds is here not important, it is ignored in the implementation)

The $read or $error arrays are allowed to be empty if the other is filled with mysqli objects.

$read has to be an array with mysqli objects you want to poll.

$error has to be an array with mysqli objects you want to check for extraordinary data.

As you see from http://lxr.php.net/xref/PHP_5_5/ext/mysqlnd/mysqlnd_enum_n_def.h#322 and http://lxr.php.net/xref/PHP_5_5/ext/mysqlnd/mysqlnd.c#1228, everything that doesn't match <= CONN_READY || == CONN_QUIT_SENT implies CONN_QUERY_SENT, CONN_SENDING_LOAD_DATA, CONN_FETCHING_DATA, CONN_NEXT_RESULT_PENDING (i.e. data is not yet ready to be fetched; names should be self-explaining) won't be added to the ready array == will be $rejected:

$rejected can be anything when you pass it to the function; it'll be overwritten with an array with the entries in $read which aren't yet ready to be read.

查看更多
登录 后发表回答