stoddard    99/10/20 13:56:04

  Modified:    src/os/win32 iol_socket.c
  Log:
  Win32: Continuing Manoj's work updating iol_socket to return ap_status_t
  
  Revision  Changes    Path
  1.6       +104 -441  apache-2.0/src/os/win32/iol_socket.c
  
  Index: iol_socket.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/os/win32/iol_socket.c,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- iol_socket.c      1999/10/08 19:07:11     1.5
  +++ iol_socket.c      1999/10/20 20:56:03     1.6
  @@ -60,11 +60,6 @@
   #include "ap_iol.h"
   #include "iol_socket.h"
   
  -#define FD_NONBLOCKING_SET   (1)
  -//#define IOL_SOCK_POSIX    // This works except for writev
  -#define IOL_SOCK_WIN32
  -//#define IOL_SOCK_ASYNC
  -
   typedef struct {
       ap_iol iol;
       int fd;
  @@ -72,7 +67,7 @@
       int timeout;
   } iol_socket;
   
  -static int win32_setopt(ap_iol *viol, ap_iol_option opt, const void *value)
  +static ap_status_t win32_setopt(ap_iol *viol, ap_iol_option opt, const void 
*value)
   {
       iol_socket *iol = (iol_socket *)viol;
   
  @@ -81,13 +76,12 @@
        iol->timeout = *(const int *)value;
        break;
       default:
  -        WSASetLastError(WSAEINVAL);
  -     return -1;
  +     return APR_EINVAL;
       }
  -    return 0;
  +    return APR_SUCCESS;
   }
   
  -static int win32_getopt(ap_iol *viol, ap_iol_option opt, void *value)
  +static ap_status_t win32_getopt(ap_iol *viol, ap_iol_option opt, void *value)
   {
       iol_socket *iol = (iol_socket *)viol;
   
  @@ -96,412 +90,131 @@
        *(int *)value = iol->timeout;
        break;
       default:
  -        WSASetLastError(WSAEINVAL);
  -     return -1;
  +     return APR_EINVAL;
       }
  -    return 0;
  +    return APR_SUCCESS;
   }
   
  -static int set_nonblock(int fd)
  +static ap_status_t set_nonblock(int fd)
   {
       int iostate = 1;
       ioctlsocket(fd, FIONBIO, &iostate);
  -    return 0;
  +    return APR_SUCCESS;
   }
   
  -static int win32_close(ap_iol *viol)
  +static ap_status_t win32_close(ap_iol *viol)
   {
       iol_socket *iol = (iol_socket *)viol;
       int rv;
   
       rv = closesocket(iol->fd);
  -
  -//    free(iol);
  -
  -    return rv;
  -}
  -#ifdef IOL_SOCK_POSIX
  -/* the timeout code is a separate routine because it requires
  -    a stack frame... and we don't want to pay that setup cost
  -    on every call */
  -
  -/* this macro expands into the four basic i/o methods */
  -
  -#define method(name, args, syscall, selread, selwrite)       \
  -    static int win32_##name##_timeout args \
  -    { \
  -     iol_socket *iol = (iol_socket *)viol; \
  -     fd_set fdset; \
  -     struct timeval tv; \
  -     int rv; \
  -        int lasterror; \
  - \
  -     FD_ZERO(&fdset); \
  -     FD_SET(iol->fd, &fdset); \
  -     tv.tv_sec = iol->timeout; \
  -     tv.tv_usec = 0; \
  -     do { \
  -         rv = select(iol->fd + 1, selread, selwrite, NULL, iol->timeout < 0 
? NULL : &tv); \
  -            if (rv == SOCKET_ERROR) { \
  -                lasterror = WSAGetLastError(); \
  -            } \
  -        } while (rv == SOCKET_ERROR && lasterror == WSAEINTR); \
  -     if (!FD_ISSET(iol->fd, &fdset)) { \
  -         WSASetLastError(WSAETIMEDOUT); \
  -         return -1; \
  -     } \
  -     do { \
  -         rv = syscall(iol->fd, arg1, arg2, 0); \
  -            if (rv == SOCKET_ERROR) { \
  -                lasterror = WSAGetLastError(); \
  -            } \
  -     } while (rv == SOCKET_ERROR && lasterror == WSAEINTR); \
  -     return rv; \
  -    } \
  - \
  -    static int win32_##name args \
  -    { \
  -     iol_socket *iol = (iol_socket *)viol; \
  -     int rv; \
  -        int lasterror; \
  - \
  -     if (!(iol->flags & FD_NONBLOCKING_SET)) { \
  -         if (iol->timeout < 0) { \
  -             return syscall(iol->fd, arg1, arg2, 0); \
  -         } \
  -         /* must shift descriptor to blocking mode now */ \
  -         if (set_nonblock(iol->fd)) { \
  -             return -1; \
  -         } \
  -         iol->flags |= FD_NONBLOCKING_SET; \
  -     } \
  - \
  -     /* try writing, ignoring EINTR, the upper layer has to handle \
  -         partial read/writes anyhow, so we can return early */ \
  -     do { \
  -            rv = syscall(iol->fd, arg1, arg2, 0); \
  -            if (rv == SOCKET_ERROR) { \
  -                lasterror = WSAGetLastError(); \
  -            } \
  -        } while (rv == SOCKET_ERROR && lasterror == WSAEINTR); \
  -     if (rv >= 0) { \
  -         return rv; \
  -     } \
  -     if (lasterror == WSAEWOULDBLOCK && iol->timeout != 0) { \
  -         return win32_##name##_timeout(viol, arg1, arg2); \
  -     } \
  -     return -1; \
  -    } \
  -
  -method(send, (ap_iol *viol, const char *arg1, int arg2), send, NULL, &fdset)
  -//method(writev, (ap_iol *viol, const struct iovec *arg1, int arg2), writev, 
NULL, &fdset)
  -method(recv, (ap_iol *viol, char *arg1, int arg2), recv, &fdset, NULL)
  -
  -
  -static const ap_iol_methods socket_methods = {
  -    win32_close,
  -    win32_send,
  -//    win32_writev,
  -    win32_recv,
  -    win32_setopt,
  -    win32_getopt
  -};
  -
  -#elif defined(IOL_SOCK_WIN32)
  -/*
  -static int win32_send(ap_iol *viol, const char *buf, int len)
  -{
  -    int rv;
  -    int lasterror;    
  -    iol_socket *iol = (iol_socket *)viol;
  -    WSABUF wsaData;
  -
  -    wsaData.len = len;
  -    wsaData.buf = (const char*) buf;
  -
  -    if (set_nonblock(iol->fd)) { 
  -        return -1;
  -    }
  -
  -    do {
  -        rv = WSASend(iol->fd, &wsaData, 1, &len, 0, NULL, NULL);
  -        if (rv == SOCKET_ERROR) {
  -            lasterror = WSAGetLastError();
  -        } 
  -    } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  -
  -    if (rv == SOCKET_ERROR && lasterror == WSAEWOULDBLOCK && iol->timeout > 
0) {
  -        struct timeval tv;
  -        fd_set fdset;
  -        int srv;
  -
  -        do {
  -            FD_ZERO(&fdset);
  -            FD_SET(iol->fd, &fdset);
  -            tv.tv_sec  = iol->timeout;
  -            tv.tv_usec = 0;
  -
  -            srv = select(FD_SETSIZE, NULL, &fdset, NULL, &tv);
  -            if (srv == SOCKET_ERROR) {
  -                lasterror = WSAGetLastError();
  -            }
  -        } while (srv == SOCKET_ERROR && errno == WSAEINTR);
  -
  -        if (srv == 0) {
  -            return -1;
  -        }
  -        if (srv < 0) {
  -            return -1;
  -        }
  -        else {
  -            do {
  -                rv = WSASend(iol->fd, &wsaData, 1, &len, 0, NULL, NULL);
  -                if (rv == SOCKET_ERROR) {
  -                    lasterror = WSAGetLastError();
  -                } 
  -            } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  -        }
  -    }
  -    else if (rv == SOCKET_ERROR) {
  -        len = -1;
  -    }
  -
  -    return len;
  -}
  -static int win32_recv( ap_iol *viol, const char *buf, int len)
  -{
  -    int rv;
  -    int lasterror;
  -    iol_socket *iol = (iol_socket *)viol;
  -    WSABUF wsaData;
  -    DWORD dwBytesRecv;
  -    DWORD flags = 0;
  -
  -    wsaData.len = len;
  -    wsaData.buf = buf;
   
  -    if (set_nonblock(iol->fd)) { 
  -        return -1;
  +    if (rv == SOCKET_ERROR) {
  +        //free(iol);
  +        return WSAGetLastError();
       }
  -
  -    do {
  -        rv = WSARecv(iol->fd, &wsaData, 1, &dwBytesRecv, &flags, NULL, NULL);
  -        if (rv == SOCKET_ERROR) {
  -            lasterror = WSAGetLastError();
  -        } 
  -        else
  -            len = dwBytesRecv;
  -    } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  -
  -    if (rv == SOCKET_ERROR && lasterror == WSAEWOULDBLOCK && iol->timeout > 
0) {
  -        struct timeval tv;
  -        fd_set fdset;
  -        int srv;
  -
  -        do {
  -            FD_ZERO(&fdset);
  -            FD_SET(iol->fd, &fdset);
  -            tv.tv_sec  = iol->timeout;
  -            tv.tv_usec = 0;
  -
  -            srv = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
  -            if (srv == SOCKET_ERROR) {
  -                lasterror = WSAGetLastError();
  -            } 
  -        } while (srv == SOCKET_ERROR && errno == WSAEINTR);
  -
  -        if (srv == 0) {
  -            return -1;
  -        }
  -        else if (srv < 0) {
  -            return -1;
  -        }
  -        else {
  -            do {
  -                rv = WSARecv(iol->fd, &wsaData, 1, &dwBytesRecv, &flags, 
NULL, NULL);
  -                if (rv == SOCKET_ERROR) {
  -                    lasterror = WSAGetLastError();
  -                } 
  -                else
  -                    len = dwBytesRecv;
  -            } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  -        }
  -    }
  -    else if (rv == SOCKET_ERROR) {
  -        len = -1;
  -    }
  -
  -    return len;
  +    //free(iol);
  +    return APR_SUCCESS;
   }
   
  -static int win32_writev(ap_iol *viol, const struct iovec *vec, int num)
  +static ap_status_t win32_write(ap_iol *viol, const char *buf, ap_size_t len, 
ap_ssize_t *nbytes)
   {
  -    int i;
       int rv;
  -    int lasterror;
  -    int len = 0;
  -    LPWSABUF pWsaData = malloc(sizeof(WSABUF) * num);
  -
  -    iol_socket *iol = (iol_socket *)viol;
  -
  -    if (!pWsaData)
  -        return -1;
  -
  -    for (i = 0; i < num; i++) {
  -        pWsaData[i].buf = vec[i].iov_base;
  -        pWsaData[i].len = vec[i].iov_len;
  -    }
  -
  -    if (set_nonblock(iol->fd)) { 
  -        free(pWsaData);
  -        return -1;
  -    }
  -
  -    do {
  -        rv = WSASend(iol->fd, pWsaData, num, &len, 0, NULL, NULL);
  -        if (rv == SOCKET_ERROR) {
  -            lasterror = WSAGetLastError();
  -        } 
  -    } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  -
  -    if (rv == SOCKET_ERROR && lasterror == WSAEWOULDBLOCK && iol->timeout > 
0) {
  -        struct timeval tv;
  -        fd_set fdset;
  -        int srv;
  -
  -        do {
  -            FD_ZERO(&fdset);
  -            FD_SET(iol->fd, &fdset);
  -            tv.tv_sec  = iol->timeout;
  -            tv.tv_usec = 0;
  -
  -            srv = select(FD_SETSIZE, NULL, &fdset, NULL, &tv);
  -            if (srv == SOCKET_ERROR) {
  -                lasterror = WSAGetLastError();
  -            }
  -        } while (srv == SOCKET_ERROR && errno == WSAEINTR);
  -
  -        if (srv == 0) {
  -            free(pWsaData);
  -            return -1;
  -        }
  -        if (srv < 0) {
  -            free(pWsaData);
  -            return -1;
  -        }
  -        else {
  -            do {
  -                rv = WSASend(iol->fd, pWsaData, num, &len, 0, NULL, NULL);
  -                if (rv == SOCKET_ERROR) {
  -                    lasterror = WSAGetLastError();
  -                } 
  -            } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  -        }
  -    }
  -    else if (rv == SOCKET_ERROR) {
  -        len = -1;
  -    }
  -
  -    free(pWsaData);
  -    return len;
  -}
  -*/
  -static int win32_send(ap_iol *viol, const char *buf, int len)
  -{
  -    int rv;
       int lasterror;    
       int timeout;
  -    iol_socket *iol = (iol_socket *)viol;
       WSABUF wsaData;
  +    DWORD dwBytesSent = 0;
  +    iol_socket *iol = (iol_socket *)viol;
   
       wsaData.len = len;
  -    wsaData.buf = (const char*) buf;
  +    wsaData.buf = (char*) buf;
   
       timeout = iol->timeout * 1000;  /* setsockopt requires timeout in 
milliseconds */
   
  -    rv = setsockopt(iol->fd, SOL_SOCKET, SO_SNDTIMEO,
  -               (char*) &timeout, sizeof(timeout));
  -    if (rv != NO_ERROR) {
  -        printf("win32send: setsockopt failed.\n");
  -        return -1;
  -    }
  -    do {
  -        rv = WSASend(iol->fd, &wsaData, 1, &len, 0, NULL, NULL);
  -        if (rv != SOCKET_ERROR) {
  -            return len;
  -        }
  -        else {
  -            lasterror = WSAGetLastError();
  -        } 
  -    } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  -
  -    /* TEST CODE
  -     * If lasterror ==WSATIMEDOUT, then the connection timed out 
  -     */
  -    if (rv == SOCKET_ERROR && lasterror == WSAETIMEDOUT) {
  -        printf("wsasend: Connection timed out\n");
  -    } else {
  -        printf("Connection failed. lasterror = %d\n", lasterror);
  +    rv = setsockopt(iol->fd, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, 
  +                    sizeof(timeout));
  +    if (rv == SOCKET_ERROR) {
  +        return WSAGetLastError();
  +    }
  +
  +    rv = WSASend(iol->fd, &wsaData, 1, &dwBytesSent, 0, NULL, NULL);
  +    if (rv == SOCKET_ERROR) {
  +        /* Note: 
  +         * Windows function calls do not normally fail with EINTR. If they 
do,
  +         * consider it an unrecoverable error and do not 'try-again'
  +         * Future:
  +         * This code will need modification when we begin supporting 
overlapped 
  +         * I/O (when WSA_IO_PENDING could be received). 
  +         */
  +        *nbytes = 0;
  +        lasterror = WSAGetLastError();
  +        if (lasterror == WSAETIMEDOUT)
  +            printf("wsasend: Connection timed out\n");
  +        else
  +            printf("wsasend: connection failed. lasterror = %d\n", 
lasterror);            
  +        return lasterror;
       }
   
  -    return -1;
  +    *nbytes = dwBytesSent;
  +
  +    return APR_SUCCESS;
   }
  -static int win32_recv( ap_iol *viol, const char *buf, int len)
  +static ap_status_t win32_recv( ap_iol *viol, const char *buf, ap_size_t len, 
ap_ssize_t *nbytes)
   {
       int rv;
       int lasterror;
       int timeout;
  -    iol_socket *iol = (iol_socket *)viol;
  -
       WSABUF wsaData;
       DWORD dwBytesRecv;
       DWORD flags = 0;
  +    iol_socket *iol = (iol_socket *)viol;
   
       wsaData.len = len;
  -    wsaData.buf = buf;
  +    wsaData.buf = (char*) buf;
   
       timeout = iol->timeout * 1000;  /* setsockopt requires timeout in 
milliseconds */
   
  -    rv = setsockopt(iol->fd, SOL_SOCKET, SO_RCVTIMEO,
  -               (char*) &timeout, sizeof(timeout));
  -    if (rv != NO_ERROR) {
  -        printf("win32recv: setsockopt failed. errno = %d\n", 
WSAGetLastError());
  -        return -1;
  -    }
  -    do {
  -        rv = WSARecv(iol->fd, &wsaData, 1, &dwBytesRecv, &flags, NULL, NULL);
  -        if (rv != SOCKET_ERROR) {
  -            return (int) dwBytesRecv;
  -        }
  -        else {
  -            lasterror = WSAGetLastError();
  -        }
  -    } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  -
  -    /* TEST CODE
  -     * If lasterror ==WSATIMEDOUT, then the connection timed out 
  -     */
  -    if (rv == SOCKET_ERROR && lasterror == WSAETIMEDOUT) {
  -        printf("wsarecv: Connection timed out\n");
  -    } else {
  -        printf("Connection failed. lasterror = %d\n", lasterror);
  +    rv = setsockopt(iol->fd, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, 
  +                    sizeof(timeout));
  +    if (rv == SOCKET_ERROR) {
  +        return WSAGetLastError();
  +    }
  +
  +    rv = WSARecv(iol->fd, &wsaData, 1, &dwBytesRecv, &flags, NULL, NULL);
  +    if (rv == SOCKET_ERROR) {
  +        /* Note: 
  +         * Windows function calls do not normally fail with EINTR. If they 
do,
  +         * consider it an unrecoverable error and do not 'try-again'
  +         * Future:
  +         * This code will need modification when we begin supporting 
overlapped 
  +         * I/O (when WSA_IO_PENDING could be received). 
  +         */
  +        *nbytes = 0;
  +        lasterror = WSAGetLastError();
  +        if (lasterror == WSAETIMEDOUT)
  +            printf("wsarecv: Connection timed out\n");
  +        else
  +            printf("wsarecv: connection failed. lasterror = %d\n", 
lasterror);            
  +        return lasterror;
       }
   
  -    return -1;
  +    *nbytes = dwBytesRecv;
  +
  +    return APR_SUCCESS;
   }
   
  -static int win32_writev(ap_iol *viol, const struct iovec *vec, int num)
  +static ap_status_t win32_writev(ap_iol *viol, const struct iovec *vec, int 
num, ap_ssize_t *nbytes)
   {
       int i;
       int rv;
       int lasterror;
  -    int len = 0;
       int timeout;
  +    DWORD dwBytesSent = 0;
       iol_socket *iol = (iol_socket *)viol;
  -
       LPWSABUF pWsaData = malloc(sizeof(WSABUF) * num);
  +
       if (!pWsaData)
  -        return -1;
  +        return APR_ENOMEM;
   
       for (i = 0; i < num; i++) {
           pWsaData[i].buf = vec[i].iov_base;
  @@ -510,98 +223,48 @@
   
       timeout = iol->timeout * 1000;  /* setsockopt requires timeout in 
milliseconds */
   
  -    rv = setsockopt(iol->fd, SOL_SOCKET, SO_SNDTIMEO,
  -               (char*) &timeout, sizeof(timeout));
  -    if (rv != NO_ERROR) {
  -        printf("win32recv: setsockopt failed. errno = %d\n", 
WSAGetLastError());
  -        return -1;
  -    }
  +    rv = setsockopt(iol->fd, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, 
  +                    sizeof(timeout));
  +    if (rv == SOCKET_ERROR) {
  +        lasterror = WSAGetLastError();
  +        printf("win32_writev: setsockopt failed. errno = %d\n", lasterror);
  +        return lasterror;
  +    }
  +
  +    rv = WSASend(iol->fd, pWsaData, num, &dwBytesSent, 0, NULL, NULL);
  +    if (rv == SOCKET_ERROR) {
  +        /* Note: 
  +         * Windows function calls do not normally fail with EINTR. If they 
do,
  +         * consider it an unrecoverable error and do not 'try-again'
  +         * Future:
  +         * This code will need modification when we begin supporting 
overlapped 
  +         * I/O (when WSA_IO_PENDING could be received). 
  +         */
  +        *nbytes = 0;
  +        lasterror = WSAGetLastError();
  +        if (lasterror == WSAETIMEDOUT)
  +            printf("wsasend: Connection timed out\n");
  +        else
  +            printf("wsasend: connection failed. lasterror = %d\n", 
lasterror);            
   
  -    do {
  -        rv = WSASend(iol->fd, pWsaData, num, &len, 0, NULL, NULL);
  -        if (rv != SOCKET_ERROR) {
  -            free(pWsaData);
  -            return len;
  -        } 
  -        else {
  -            lasterror = WSAGetLastError();
  -        }
  -    } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  -
  -    /* TEST CODE
  -     * If lasterror ==WSATIMEDOUT, then the connection timed out 
  -     */
  -    if (rv == SOCKET_ERROR && lasterror == WSAETIMEDOUT) {
  -        printf("wsarecv: Connection timed out\n");
  -    } else {
  -        printf("Connection failed. lasterror = %d\n", lasterror);
  +        free(pWsaData);
  +        return lasterror;
       }
  -    free(pWsaData);
  -    return -1;
  -}
  -static const ap_iol_methods socket_methods = {
  -    win32_close,
  -    win32_send,
  -    win32_writev,
  -    win32_recv,
  -    win32_setopt,
  -    win32_getopt
  -};
   
  -#elif defined(IOL_SOCK_ASYNC)
  +    free(pWsaData);
   
  -static int win32_read(ap_iol *viol, const char *buf, int bufSize) 
  -{
  -    int rc;
  -    iol_socket *iol = (iol_socket *) viol;
  +    *nbytes = dwBytesSent;
   
  -    DWORD BytesRecvd;
  -    DWORD flags;
  -    WSAOVERLAPPED Overlapped;
  -    WSABUF wsaBuf;
  -
  -    wsaBuf.u_longlen = bufSize;
  -    wsaBuf.buf = buf;
  -    
  -    Overlapped.Internal = ;
  -    Overlapped.InternalHigh = ;
  -    Overlapped.Offset = ;
  -    Overlapped.OffsetHigh = ;
  -    Overlapped.hEvent = CreateEvent(...);
  -
  -    rc = WSARecv(iol->fd,
  -                 &wsaBuf,
  -                 (DWORD) 1,
  -                 &BytesRecvd,
  -                 &flags,
  -                 &Overlapped,
  -                 NULL); 
  -    if (rc == SOCKET_ERROR) {
  -        if (WSAGetLastError() == WSA_IO_PENDING) {
  -            rc = WSAWaitForMultipleEvents(1,                    // wait for 
1 event
  -                                          &Overlapped.hEvent, 
  -                                          TRUE,                 // wait for 
all events to be satisfied
  -                                          (DWORD) iol->timeout, // timeout 
in milliseconds
  -                                          FALSE);
  -            if (rc == WSA_WAIT_FAILED)
  -        }
  -        else {
  -        }
  -        if (timeout
  -    }
  -                             
  +    return APR_SUCCESS;
   }
  -
   static const ap_iol_methods socket_methods = {
       win32_close,
  -    win32_send,
  +    win32_write,
       win32_writev,
       win32_recv,
       win32_setopt,
       win32_getopt
   };
  -
  -#endif
   
   ap_iol *win32_attach_socket(ap_context_t *p, int fd)
   {
  
  
  

Reply via email to