ID:               46917
 User updated by:  jost_boekemeier at users dot sf dot net
 Reported By:      jost_boekemeier at users dot sf dot net
-Status:           Closed
+Status:           Open
 Bug Type:         Streams related
 Operating System: *
 PHP Version:      5.2.8
 New Comment:

Hi,

the code is okay for Linux, but on Windows it fails constantly.

+       WSASetLastError(0);
        n = select(max_fd + 1, &rset, &wset, &eset, timeout >= 0 ? &tv :
NULL);

IMHO this means that select always returns EAGAIN on windows, so that
the following test cannot detect a broken connection. As I've said, I am
not sure what the EAGAIN test should do, anyway.


To reproduce this: 

1) start a simple socket server on windows >= xp, call pfsockopen() and
let the PHP instance return to the HTTP server's pool w/o closing the
connection

2) kill the socket server and start it again

3) pull the PHP instance from the pool and call pfsockopen() again.
pfsockopen() will use the broken connection until you kill the pool
(i.e.: restart apache or IIS).


Regards,
Jost Bökemeier


Previous Comments:
------------------------------------------------------------------------

[2009-01-03 17:00:01] fel...@php.net

This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

I added the Win part minutes ago:
-#ifndef PHP_WIN32
+/* Reseting/initializing */
+#ifdef PHP_WIN32
+       WSASetLastError(0);
+#else
        errno = 0;
 #endif

Ok, then, closed. Thanks.

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

[2009-01-03 16:45:50] jost_boekemeier at users dot sf dot net

Yes, this patch fixes the problem on Linux.

What about Windows?



Regards,
Jost Boekemeier

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

[2009-01-02 21:31:43] fel...@php.net

Hi, I've commited a probable fix, I initialized the errno.
http://news.php.net/php.cvs/55296

Can you test it with a cvs version again?

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

[2008-12-26 17:28:10] jost_boekemeier at users dot sf dot net

Due to its nature (uninitialized variable) you may or may not be able
to reproduce this bug. See
http://sourceforge.net/mailarchive/forum.php?thread_name=828E3F73B78941EAB5AF3E2E07C37D8D%40IBM1020C944423&forum_name=php-java-bridge-users
for details.

However, you should immediately see the bug by looking at the PHP
source code: 

  0 == recv(sock->socket, &buf, sizeof(buf), MSG_PEEK

does NOT set errno (the result code is 0, not -1) so that errno
contains a bogus value, most likely the error code from a previously
failed sys call, so that

  php_socket_errno() != EAGAIN

fails, depending on the application's PHP code, as errno sometimes
contains EAGAIN (from a previous poll()).


Just search the PHP sources for the pattern


} else if (php_pollfd_for(sock->socket, PHP_POLLREADABLE|POLLPRI, &tv)
>
0) {
 if (0 == recv(sock->socket, &buf, sizeof(buf), MSG_PEEK) &&
php_socket_errno() != EAGAIN) {
        alive = 0;
}


and set the errno or the lastErrorCode (for windows) to zero before
calling this pattern. 

After that persistent sockets, soap and a few other places will work
reliably.

There are a few caveats, however. First, if you pass the last error
number to application-level, you might have to restore the last errno
immediately after the recv call. Second, I don't know what the
php_socket_errno() != EAGAIN should do, anyway, as EAGAIN is only set
when the previous sys call failed (result code -1, not 0!). So I suggest
to ask the author to explain his/her code before fixing anything.


Regards,
Jost Bökemeier

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

[2008-12-24 19:48:34] fel...@php.net

Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.



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

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/46917

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

Reply via email to