stoddard 00/01/25 21:56:43
Modified: src/include ap_iol.h src/lib/apr aprlib.def src/lib/apr/include apr_network_io.h apr_win.h apr_winconfig.h src/lib/apr/network_io/win32 sendrecv.c src/os/win32 iol_socket.c iol_socket.h Log: Begin migrating Windows to use APR sockets. Clean-up sendfile a bit more. Revision Changes Path 1.9 +3 -1 apache-2.0/src/include/ap_iol.h Index: ap_iol.h =================================================================== RCS file: /home/cvs/apache-2.0/src/include/ap_iol.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ap_iol.h 1999/11/02 14:30:26 1.8 +++ ap_iol.h 2000/01/26 05:56:33 1.9 @@ -112,7 +112,9 @@ ap_ssize_t *nbytes); ap_status_t (*setopt)(ap_iol *fd, ap_iol_option opt, const void *value); ap_status_t (*getopt)(ap_iol *fd, ap_iol_option opt, void *value); - ap_status_t (*sendfile)(ap_iol *fd, ap_file_t *file, long size, const char *header, long hdrlen, int flags); + ap_status_t (* sendfile)(ap_iol *fd, ap_file_t * file, ap_hdtr_t * hdtr, + ap_off_t * offset, ap_size_t * len, + ap_int32_t flags); /* TODO: accept, connect, ... */ }; 1.9 +2 -2 apache-2.0/src/lib/apr/aprlib.def Index: aprlib.def =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/aprlib.def,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- aprlib.def 2000/01/17 04:42:20 1.8 +++ aprlib.def 2000/01/26 05:56:36 1.9 @@ -65,8 +65,8 @@ ap_send @56 ap_recv @57 ap_setsocketopt @58 -; ap_getport @59 -; ap_setport @60 + ap_sendv @59 + ap_sendfile @60 ap_setup_poll @61 ap_poll @62 ap_add_poll_socket @63 1.21 +1 -1 apache-2.0/src/lib/apr/include/apr_network_io.h Index: apr_network_io.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_network_io.h,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- apr_network_io.h 2000/01/19 01:14:57 1.20 +++ apr_network_io.h 2000/01/26 05:56:38 1.21 @@ -155,7 +155,7 @@ ap_status_t ap_send(ap_socket_t *, const char *, ap_ssize_t *); ap_status_t ap_sendv(ap_socket_t *sock, const struct iovec *vec, ap_int32_t nvec, ap_int32_t *nbytes); -#ifdef HAVE_SENDFILE +#if APR_HAS_SENDFILE ap_status_t ap_sendfile(ap_socket_t *sock, ap_file_t *file, ap_hdtr_t *hdtr, ap_off_t *offset, ap_size_t *len, ap_int32_t flags); #endif 1.14 +1 -1 apache-2.0/src/lib/apr/include/apr_win.h Index: apr_win.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_win.h,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- apr_win.h 2000/01/24 03:03:49 1.13 +++ apr_win.h 2000/01/26 05:56:38 1.14 @@ -103,7 +103,7 @@ /* APR Feature Macros */ #define APR_HAS_THREADS 1 -#define APR_HAS_SENDFILE 0 +#define APR_HAS_SENDFILE 1 #define APR_HAS_MMAP 0 /* Typedefs that APR needs. */ 1.3 +6 -0 apache-2.0/src/lib/apr/include/apr_winconfig.h Index: apr_winconfig.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_winconfig.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- apr_winconfig.h 1999/12/14 15:28:21 1.2 +++ apr_winconfig.h 2000/01/26 05:56:38 1.3 @@ -53,6 +53,9 @@ * */ +/* + * Note: This is the windows specific autoconf like config file (apr_config.h) + */ #ifdef WIN32 #ifndef APR_WINCONFIG_H @@ -75,6 +78,9 @@ #include <stddef.h> #include <stdio.h> #include <time.h> + + +#define HAVE_SENDFILE 1 /* Use this section to define all of the HAVE_FOO_H * that are required to build properly. 1.5 +29 -24 apache-2.0/src/lib/apr/network_io/win32/sendrecv.c Index: sendrecv.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/sendrecv.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- sendrecv.c 2000/01/24 20:58:20 1.4 +++ sendrecv.c 2000/01/26 05:56:40 1.5 @@ -195,13 +195,13 @@ ap_int32_t flags) { ap_ssize_t rv; - OVERLAPPED Overlapped, *pOverlapped; - TRANSMIT_FILE_BUFFERS TFBuffs, *pTFBuffs; +#ifdef OVERLAPPED + OVERLAPPED overlapped; +#endif + TRANSMIT_FILE_BUFFERS tfb, *ptfb = NULL; int i, lasterror, ptr = 0; - int timeout = sock->timeout * 1000; /* Need timeout in milliseconds */ DWORD dwFlags = 0; - size_t headerlen = 0, trailerlen = 0; - void *headerbuf, *trailerbuf; + int timeout = sock->timeout * 1000; /* Need timeout in milliseconds */ rv = setsockopt(sock->sock, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, sizeof(timeout)); @@ -211,50 +211,55 @@ if (flags | APR_SENDFILE_CLOSE_SOCKET) dwFlags |= TF_DISCONNECT; #else - dwFlags = 0; // TF_DISCONNECT;TF_WRITE_BEHIND;TF_REUSE_SOCKET; + dwFlags = 0; #endif /* TransmitFile can only send one header and one footer */ - pTFBuffs = NULL; - memset(&TFBuffs, '0', sizeof (TFBuffs)); + memset(&tfb, '0', sizeof (tfb)); if (hdtr->numheaders) { + ptfb = &tfb; for (i = 0; i < hdtr->numheaders; i++) { - TFBuffs.HeadLength += hdtr->headers[i].iov_len; + tfb.HeadLength += hdtr->headers[i].iov_len; } - TFBuffs.Head = ap_palloc(sock->cntxt, headerlen); /* should this be a malloc? */ + tfb.Head = ap_palloc(sock->cntxt, tfb.HeadLength); /* Should this be a malloc? */ for (i = 0; i < hdtr->numheaders; i++) { - memcpy(&TFBuffs.Head, hdtr->headers[i].iov_base + ptr, + memcpy(&tfb.Head + ptr, hdtr->headers[i].iov_base, hdtr->headers[i].iov_len); ptr += hdtr->headers[i].iov_len; } - pTFBuffs = &TFBuffs; } if (hdtr->numtrailers) { + ptfb = &tfb; for (i = 0; i < hdtr->numtrailers; i++) { - TFBuffs.TailLength += hdtr->headers[i].iov_len; + tfb.TailLength += hdtr->headers[i].iov_len; } - TFBuffs.Tail = ap_palloc(sock->cntxt, trailerlen); /* Should this be a malloc */ + tfb.Tail = ap_palloc(sock->cntxt, tfb.TailLength); /* Should this be a malloc? */ for (i = 0; i < hdtr->numtrailers; i++) { - memcpy(&TFBuffs.Tail, hdtr->trailers[i].iov_base + ptr, + memcpy(&tfb.Tail + ptr, hdtr->trailers[i].iov_base, hdtr->trailers[i].iov_len); ptr += hdtr->trailers[i].iov_len; } - pTFBuffs = &TFBuffs; - } -// memset(&overlapped,'0', sizeof(overlapped)); - rv = TransmitFile(sock->sock, /* socket */ + } +#ifdef OVERLAPPED + memset(&overlapped,'0', sizeof(overlapped)); +#endif + rv = TransmitFile(sock->sock, /* socket */ file->filehand, /* open file descriptor of the file to be sent */ - *len, /* number of bytes to send. 0==> send all */ - 0, /* Number of bytes per send. 0=> use default */ - NULL, /* OVERLAPPED structure */ - pTFBuffs, /* header and trailer buffers */ - dwFlags); /* flags to control various aspects of TransmitFIle */ + *len, /* number of bytes to send. 0=send all */ + 0, /* Number of bytes per send. 0=use default */ +#ifdef OVERLAPPED + &overlapped, +#else + NULL, /* OVERLAPPED structure */ +#endif + ptfb, /* header and trailer buffers */ + dwFlags); /* flags to control various aspects of TransmitFile */ if (!rv) { lasterror = WSAGetLastError(); printf("TransmitFile failed with error %d\n", lasterror); 1.9 +26 -199 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.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- iol_socket.c 1999/12/15 01:00:03 1.8 +++ iol_socket.c 2000/01/26 05:56:41 1.9 @@ -54,18 +54,15 @@ * project, please see <http://www.apache.org/>. * */ - - #include "httpd.h" #include "ap_iol.h" #include "iol_socket.h" #include "apr_portable.h" +#include <malloc.h> typedef struct { ap_iol iol; - int fd; - int flags; - int timeout; + ap_socket_t *sock; } iol_socket; static ap_status_t win32_setopt(ap_iol *viol, ap_iol_option opt, const void *value) @@ -74,7 +71,7 @@ switch (opt) { case AP_IOL_TIMEOUT: - iol->timeout = *(const int *)value; + ap_setsocketopt(iol->sock, APR_SO_TIMEOUT, *(const int*)value); break; default: return APR_EINVAL; @@ -88,226 +85,58 @@ switch (opt) { case AP_IOL_TIMEOUT: - *(int *)value = iol->timeout; +#if 0 + *(int *)value = iol->timeout; // ToDo: Impleent this +#endif break; default: return APR_EINVAL; } return APR_SUCCESS; } - -static ap_status_t set_nonblock(int fd) -{ - int iostate = 1; - ioctlsocket(fd, FIONBIO, &iostate); - return APR_SUCCESS; -} - static ap_status_t win32_close(ap_iol *viol) { iol_socket *iol = (iol_socket *)viol; - int rv; - - rv = closesocket(iol->fd); - - if (rv == SOCKET_ERROR) { - //free(iol); - return WSAGetLastError(); - } - //free(iol); - return APR_SUCCESS; + return ap_close_socket(iol->sock); } -static ap_status_t win32_write(ap_iol *viol, const char *buf, ap_size_t len, ap_ssize_t *nbytes) +static ap_status_t win32_write(ap_iol *viol, const char *buf, ap_size_t len, + ap_ssize_t *nbytes) { - int rv; - int lasterror; - int timeout; - WSABUF wsaData; - DWORD dwBytesSent = 0; - iol_socket *iol = (iol_socket *)viol; - - wsaData.len = len; - 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 == 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; - } - - *nbytes = dwBytesSent; - - return APR_SUCCESS; + *nbytes = len; + return ap_send(((iol_socket *)viol)->sock, buf, nbytes); } -static ap_status_t win32_recv( ap_iol *viol, const char *buf, ap_size_t len, ap_ssize_t *nbytes) +static ap_status_t win32_read( ap_iol *viol, char *buf, ap_size_t len, + ap_ssize_t *nbytes) { - int rv; - int lasterror; - int timeout; - WSABUF wsaData; - DWORD dwBytesRecv; - DWORD flags = 0; - iol_socket *iol = (iol_socket *)viol; - - wsaData.len = len; - 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 == 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; - } - - *nbytes = dwBytesRecv; - - return APR_SUCCESS; + *nbytes = len; + return ap_recv(((iol_socket *)viol)->sock, buf, nbytes); } -static ap_status_t win32_writev(ap_iol *viol, const struct iovec *vec, int num, ap_ssize_t *nbytes) +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 timeout; - DWORD dwBytesSent = 0; - iol_socket *iol = (iol_socket *)viol; - LPWSABUF pWsaData = malloc(sizeof(WSABUF) * num); - - if (!pWsaData) - return APR_ENOMEM; - - for (i = 0; i < num; i++) { - pWsaData[i].buf = vec[i].iov_base; - pWsaData[i].len = vec[i].iov_len; - } - - timeout = iol->timeout * 1000; /* setsockopt requires timeout in milliseconds */ - - 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); - - free(pWsaData); - return lasterror; - } - - free(pWsaData); - - *nbytes = dwBytesSent; - - return APR_SUCCESS; + return ap_sendv(((iol_socket *)viol)->sock, vec, num, nbytes); } -static ap_status_t win32_sendfile(ap_iol *viol, ap_file_t *file, long filelen, - const char *header, long hdrlen, int flags) -{ - int rv; - int lasterror; - int timeout; - HANDLE nfd; - DWORD dwFlags = 0; - iol_socket *iol = (iol_socket *)viol; - ap_get_os_file(&nfd, file); - - timeout = iol->timeout * 1000; /* setsockopt requires timeout in milliseconds */ - - rv = setsockopt(iol->fd, SOL_SOCKET, SO_SNDTIMEO, - (char*) &timeout, sizeof(timeout)); -#if 0 - if (flags | APR_SENDFILE_KEEP_SOCKET) - dwFlags |= TF_REUSE_SOCKET; - if (flags | APR_SENDFILE_CLOSE_SOCKET) - dwFlags |= TF_DISCONNECT; -#else - dwFlags = 0; // TF_DISCONNECT;TF_WRITE_BEHIND;TF_REUSE_SOCKET; -#endif - rv = TransmitFile(iol->fd, /* socket */ - nfd, /* open file descriptor of the file to be sent */ - filelen, /* number of bytes to send. 0==> send all */ - 0, /* Number of bytes per send. 0=> use default */ - NULL, /* OVERLAPPED structure */ - NULL, /* header and trailer buffers */ - dwFlags); /* flags to control various aspects of TransmitFIle */ - if (!rv) { - lasterror = WSAGetLastError(); - printf("TransmitFile failed with error %d\n", lasterror); - return lasterror; - } - return APR_SUCCESS; +static ap_status_t win32_sendfile(ap_iol *viol, ap_file_t *file, + ap_hdtr_t *hdtr, ap_off_t *offset, + ap_size_t *len, ap_int32_t flags) +{ + return ap_sendfile(((iol_socket *)viol)->sock, file, hdtr, offset, len, flags); } static const ap_iol_methods socket_methods = { win32_close, win32_write, win32_writev, - win32_recv, + win32_read, win32_setopt, win32_getopt, win32_sendfile }; -ap_iol *win32_attach_socket(ap_context_t *p, int fd) +ap_iol *win32_attach_socket(ap_context_t *p, ap_socket_t *sock) { iol_socket *iol; @@ -316,8 +145,6 @@ if (!iol) return (ap_iol*) NULL; iol->iol.methods = &socket_methods; - iol->fd = fd; - iol->timeout = -1; - iol->flags = 0; + iol->sock = sock; return (ap_iol *)iol; } 1.4 +1 -1 apache-2.0/src/os/win32/iol_socket.h Index: iol_socket.h =================================================================== RCS file: /home/cvs/apache-2.0/src/os/win32/iol_socket.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- iol_socket.h 1999/10/08 19:07:12 1.3 +++ iol_socket.h 2000/01/26 05:56:42 1.4 @@ -58,7 +58,7 @@ #ifndef OS_WIN32_IOL_SOCKET_H #define OS_WIN32_IOL_SOCKET_H -ap_iol *win32_attach_socket(ap_context_t *p, int fd); +ap_iol *win32_attach_socket(ap_context_t *p, ap_socket_t *sock); #endif