You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by jf...@yahoo.com on 2002/06/04 00:31:26 UTC

[PATCH] WIN32 implementation of apr_poll_revents_get()

Consider this piece of code, where essentially a server poll() on its socket,
waiting for any client connections, then on any event received from poll,
test for errors (eg. the server socket has been closed),
and THEN do an accept() to get the client's connected socket:

...

/* Here we wait indefinitely... */
ret = apr_poll(poll, &n, -1);
if (ret != APR_SUCCESS) return NULL;

ret = apr_poll_revents_get(&event, sock_srvr, poll);
if (ret != APR_SUCCESS) return NULL;

/* Verify if there was any error */
if (event & (APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)) {
    apr_socket_close(sock_srvr);
    return NULL;
}

/* Ok there was a connection from a client */
ret = apr_accept(&sock_client, sock_srvr, context);
if (ret != APR_SUCCESS) return NULL;

...

This will work on UNIX (I have tested it on SunOS 5.6, HPUX 11.00, AIX 4.2 and AIX 5.1)
but it fails on WIN32.
The reason is that in apr_poll_revents_get() function, WSARecv() returns error 10057,
which is WSAENOTCONN, which means: "The socket is not connected.".
I trap this returned error code to make an additional test to see if there is indeed an error.

Here is the diff :

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

--- apr/network_io/win32/poll.c	Wed Mar 13 15:39:25 2002
+++ apr_new/network_io/win32/poll.c	Mon Jun  3 18:23:30 2002
@@ -177,6 +177,22 @@
                     revents |= APR_POLLHUP;
                     break;
                 }
+                case WSAENOTCONN: {
+                    /* Maybe the socket is created and listening, but not connected,
+                     * so everything is fine.
+                     */
+                    BOOL rep;
+                    int  sz_rep = sizeof(rep);
+
+                    if (getsockopt(sock->sock, SOL_SOCKET, SO_ACCEPTCONN, &rep, &sz_rep) != SOCKET_ERROR) {
+                        if (rep) {
+                            break; /* no error */
+                        }
+                    }
+                    revents ^= APR_POLLIN;
+                    revents |= APR_POLLERR;
+                    break;
+                }
                 case WSAENOTSOCK: {
                     revents ^= APR_POLLIN;
                     revents |= APR_POLLNVAL;

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

Jean-Francois BRIERE