Bug #65486 [Asn->Csd]: mysqli_poll() is broken on win x64
| From: | ab@php.net | Date: | Fri, 13 Dec 2013 15:12:06 +0000 |
| Subject: | Bug #65486 [Asn->Csd]: mysqli_poll() is broken on win x64 | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-183317@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=65486&edit=1
ID: 65486
Updated by: ab@php.net
Reported by: ab@php.net
Summary: mysqli_poll() is broken on win x64
-Status: Assigned
+Status: Closed
Type: Bug
Package: MySQLi related
Operating System: Windows 64 Bit
PHP Version: 5.5Git-2013-08-20 (Git)
Assigned To: ab
Block user comment: N
Private report: N
New Comment:
fixed with da62fd5ed824bafc4dc3e90278c3d57d8e74cbe1
Previous Comments:
------------------------------------------------------------------------
[2013-12-03 19:45:11] ab@php.net
Hi Andrey,
that's true, i also can see some similar code in the cli server. Regarding windows, especially
64 bit, i'd call it "fail ready". In linux there's no disctinction between file
descriptor and socket descriptor, both are some integer and 32 bit on x86 and x64 platform. On
windows there's ditinction between SOCKET and file descriptor, whereby SOCKET is unsigned and
additionally 64 bit on x64 platform. I can't tell why it works in other cases :) ... just
haven't time to debug deep. For instance I can imagine this flow could be breaking the max_fd
variable in _mysqlnd_poll()
php5ts_debug.dll!php_sockop_cast(_php_stream * stream, int castas, void * * ret, void * * * tsrm_ls)
Line 429 C
php5ts_debug.dll!_php_stream_cast(_php_stream * stream, int castas, void * * ret, int show_err, void
* * * tsrm_ls) Line 309 C
php5ts_debug.dll!mysqlnd_stream_array_to_fd_set(st_mysqlnd_connection * * conn_array, fd_set * fds,
unsigned __int64 * max_fd, void * * * tsrm_ls) Line 1280 C
php5ts_debug.dll!_mysqlnd_poll(st_mysqlnd_connection * * r_array, st_mysqlnd_connection * * e_array,
st_mysqlnd_connection * * * dont_poll, long sec, long usec, unsigned int * desc_num, void * * *
tsrm_ls) Line 1361 C
php_mysqli.dll!zif_mysqli_poll(int ht, _zval_struct * return_value, _zval_struct * *
return_value_ptr, _zval_struct * this_ptr, int return_value_used, void * * * tsrm_ls) Line 800 C
As there in xp_socket.c around line 429 is
*(int*)ret = sock->socket
On x64 windows int is 32 bit, pointer and SOCKET (so php_socket_t) are 64 bit. As one can see, the
code is very tricky in that case :)
But the big joke is, that at the other 3-4 places similar code works. Unfortunately earlier i
didn't realize the similarity you've pointed to. Maybe that thing should be fixed globally
then, as the basic issue on windows is casting int (descritors) vs. SOCKET, which are different
things using different APIs. Using SOCKET as descriptor might work but is rather an exception,
windows needs two different select()s for those.
Best regards
Anatol
------------------------------------------------------------------------
[2013-12-03 14:33:56] andrey@php.net
Anatol,
except for the bug that mysqlnd converts internally the int to uint when passing back through an out
desc_num parameter of _mysqlnd_poll() everything else is more or less copied from another part of
the distribution. The code exists in 2 places : streamfuncs.c and sockets.c (search for
"Solaris + BSD"). Is the code in this places also not correct?
Best,
Andrey
------------------------------------------------------------------------
[2013-08-20 09:01:58] ab@php.net
Description:
------------
mysqli_poll() in user space invokes _mysqlnd_poll(). In that function
php_select()
is used for polling. The windows implementation works with int for descriptors,
however php_socket_t data type is used in mysqli. This has two flaws
- generally on windows, php_socket_t is a typedef from SOCKET and is unsigned,
that means any usual UNIX socket checks want work, say checking if descriptor is
negative
- on 64 bit windows this is a breach, because SOCKET there is unsigned 64 bit
integer while php_select() implementation still uses 32 bit integers.
php_select()
internally calls select(), which on windows expects an 32 bit integer as
descriptor as well.
As result mysqli_poll* function family is broken on 64 bit Windows.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=65486&edit=1