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);