stoddard 99/08/18 08:09:38
Modified: mpm/src/main buff.c mpm/src/os/win32 iol_socket.c Added: mpm/src/os/win32 iol_socket.h Log: WIN32: Emulate Unix writev. Revision Changes Path 1.9 +9 -2 apache-2.0/mpm/src/main/buff.c Index: buff.c =================================================================== RCS file: /home/cvs/apache-2.0/mpm/src/main/buff.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- buff.c 1999/08/06 00:54:29 1.8 +++ buff.c 1999/08/18 15:09:36 1.9 @@ -63,9 +63,16 @@ #include <stdio.h> #include <stdarg.h> #include <string.h> -#ifndef NO_WRITEV #include <sys/types.h> + +/* This writev sillyness will go away with APR. */ +#ifndef NO_WRITEV #include <sys/uio.h> +#else +#ifdef WIN32 +/* Include code to emulate writev on WIN32 */ +#include <../os/win32/iol_socket.h> +#endif #endif #ifdef HAVE_BSTRING_H @@ -193,7 +200,7 @@ { switch (optname) { case BO_BYTECT: - fb->bytes_sent = *(const long int *) optval - (long int) fb->outcnt;; + fb->bytes_sent = *(const long int *) optval - (long int) fb->outcnt; return 0; case BO_TIMEOUT: 1.2 +97 -6 apache-2.0/mpm/src/os/win32/iol_socket.c Index: iol_socket.c =================================================================== RCS file: /home/cvs/apache-2.0/mpm/src/os/win32/iol_socket.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- iol_socket.c 1999/08/17 21:25:31 1.1 +++ iol_socket.c 1999/08/18 15:09:37 1.2 @@ -58,10 +58,11 @@ #include "httpd.h" #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 // ANd this seems to be working as well, except for writev... +#define IOL_SOCK_WIN32 //#define IOL_SOCK_ASYNC typedef struct { @@ -197,6 +198,15 @@ 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) @@ -207,7 +217,7 @@ WSABUF wsaData; wsaData.len = len; - wsaData.buf = buf; + wsaData.buf = (const char*) buf; if (set_nonblock(iol->fd)) { return -1; @@ -324,6 +334,86 @@ return len; } +static int win32_writev(ap_iol *viol, const struct iovec *vec, int num) +{ + 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 const ap_iol_methods socket_methods = { + win32_close, + win32_send, + win32_writev, + win32_recv, + win32_setopt, + win32_getopt +}; + #elif defined(IOL_SOCK_ASYNC) static int win32_read(ap_iol *viol, const char *buf, int bufSize) @@ -354,9 +444,9 @@ NULL); if (rc == SOCKET_ERROR) { if (WSAGetLastError() == WSA_IO_PENDING) { - rc = WSAWaitForMultipleEvents(1, // wait for 1 event + rc = WSAWaitForMultipleEvents(1, // wait for 1 event &Overlapped.hEvent, - TRUE, // wait for all events to be satisfied + TRUE, // wait for all events to be satisfied (DWORD) iol->timeout, // timeout in milliseconds FALSE); if (rc == WSA_WAIT_FAILED) @@ -367,16 +457,17 @@ } } -#endif static const ap_iol_methods socket_methods = { win32_close, win32_send, - NULL, //win32_writev, + win32_writev, win32_recv, win32_setopt, win32_getopt }; + +#endif ap_iol *win32_attach_socket(int fd) { 1.1 apache-2.0/mpm/src/os/win32/iol_socket.h Index: iol_socket.h =================================================================== /* ==================================================================== * Copyright (c) 1998-1999 The Apache Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * */ #ifndef OS_WIN32_IOL_SOCKET_H #define OS_WIN32_IOL_SOCKET_H /* struct iovec is needed to emulate Unix writev */ struct iovec { char* iov_base; int iov_len; }; ap_iol *win32_attach_socket(int fd); #endif