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


Reply via email to