stoddard 99/11/02 06:30:27
Modified: src/main http_protocol.c src/modules/mpm/winnt winnt.c src/os/win32 os.h iol_socket.c src/include ap_iol.h Log: First cut at adding a sendfile API to IOL. Eventually need to move iol_socket into APR... Revision Changes Path 1.33 +17 -1 apache-2.0/src/main/http_protocol.c Index: http_protocol.c =================================================================== RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.32 retrieving revision 1.33 diff -u -r1.32 -r1.33 --- http_protocol.c 1999/11/01 10:50:47 1.32 +++ http_protocol.c 1999/11/02 14:30:19 1.33 @@ -2008,7 +2008,23 @@ */ API_EXPORT(long) ap_send_fd(ap_file_t *fd, request_rec *r) { - return ap_send_fd_length(fd, r, -1); + ap_ssize_t len = r->finfo.st_size; +#ifdef HAVE_SENDFILE + ap_bflush(r->connection->client); + if (ap_get_filesize(&len, fd) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, + "ap_send_fd: ap_get_filesize failed."); + return 0; + } + if (iol_sendfile(r->connection->client->iol, fd, len, + NULL, 0, 0) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, + "ap_send_fd: iol_sendfile failed."); + } +#else + len = ap_send_fd_length(fd, r, -1); +#endif + return len; } API_EXPORT(long) ap_send_fd_length(ap_file_t *fd, request_rec *r, long length) 1.25 +1 -1 apache-2.0/src/modules/mpm/winnt/winnt.c Index: winnt.c =================================================================== RCS file: /home/cvs/apache-2.0/src/modules/mpm/winnt/winnt.c,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- winnt.c 1999/10/20 19:51:20 1.24 +++ winnt.c 1999/11/02 14:30:21 1.25 @@ -299,7 +299,7 @@ return (s_iInitCount); /* s_iInitCount == 0. Do the initailization */ - iVersionRequested = MAKEWORD(1, 1); + iVersionRequested = MAKEWORD(2, 0); err = WSAStartup((WORD) iVersionRequested, &wsaData); if (err) { s_iInitCount = -1; 1.8 +1 -0 apache-2.0/src/os/win32/os.h Index: os.h =================================================================== RCS file: /home/cvs/apache-2.0/src/os/win32/os.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- os.h 1999/10/05 06:01:32 1.7 +++ os.h 1999/11/02 14:30:23 1.8 @@ -108,6 +108,7 @@ #define MULTITHREAD #define HAVE_CANONICAL_FILENAME #define HAVE_DRIVE_LETTERS +#define HAVE_SENDFILE typedef int uid_t; typedef int gid_t; typedef int pid_t; 1.7 +41 -1 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.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- iol_socket.c 1999/10/20 20:56:03 1.6 +++ iol_socket.c 1999/11/02 14:30:24 1.7 @@ -257,13 +257,53 @@ return APR_SUCCESS; } +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 const ap_iol_methods socket_methods = { win32_close, win32_write, win32_writev, win32_recv, win32_setopt, - win32_getopt + win32_getopt, + win32_sendfile }; ap_iol *win32_attach_socket(ap_context_t *p, int fd) 1.8 +2 -0 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.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ap_iol.h 1999/10/20 19:38:20 1.7 +++ ap_iol.h 1999/11/02 14:30:26 1.8 @@ -112,6 +112,7 @@ 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); /* TODO: accept, connect, ... */ }; @@ -128,6 +129,7 @@ #define iol_read(iol, a, b, c) ((iol)->methods->read((iol), (a), (b), (c))) #define iol_setopt(iol, a, b) ((iol)->methods->setopt((iol), (a), (b))) #define iol_getopt(iol, a, b) ((iol)->methods->getopt((iol), (a), (b))) +#define iol_sendfile(iol, a, b, c, d, e) ((iol)->methods->sendfile((iol), (a), (b), (c), (d), (e))) /* the file iol */ ap_iol *ap_create_file_iol(ap_file_t *file);