Bill Stoddard wrote:

Philip Gladstone wrote:

I noticed that the performance of TransmitFile (used when EnableSendFile
On on Windows platforms) was significantly worse than EnableSendFile Off.

It turns out that the way that TransmitFile is called is *without* the
TF_WRITE_BEHIND flag. This means that TransmitFile does not complete (or
rather that the socket is not signalled) until *all the data* has been
ack'ed by the client. Windows clients send acks (roughly) every other
data packet, or after a 200ms timeout. Thus, about half the time, the
TransmitFile does not complete until this 200ms timeout has triggered.

This reduces the throughput on high speed networks significantly. On a
100Mbit LAN, the throughput drops from 11MBytes/sec to around
2.5MBytes/sec.

My question is: is there a good reason that the TF_WRITE_BEHIND flag is
not being used?

Try applying this patch to apr and let me know how it works.

Bill
$ cvs diff -u sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apr/network_io/win32/sendrecv.c,v
retrieving revision 1.64.2.1
diff -u -r1.64.2.1 sendrecv.c
--- sendrecv.c  13 Feb 2004 09:33:51 -0000      1.64.2.1
+++ sendrecv.c  12 Apr 2004 16:14:17 -0000
@@ -237,7 +237,7 @@
     apr_status_t status = APR_SUCCESS;
     apr_ssize_t rv;
     apr_off_t curoff = *offset;
-    DWORD dwFlags = 0;
+    DWORD dwFlags = TF_WRITE_BEHIND;
     DWORD nbytes;
     OVERLAPPED overlapped;
     TRANSMIT_FILE_BUFFERS tfb, *ptfb = NULL;
@@ -323,6 +323,7 @@
             /* Disconnect the socket after last send */
             if ((flags & APR_SENDFILE_DISCONNECT_SOCKET)
                     && !sendv_trailers) {
+                dwFlags = 0;
                 dwFlags |= TF_REUSE_SOCKET;
                 dwFlags |= TF_DISCONNECT;
                 disconnected = 1;
@@ -333,7 +334,6 @@
 #if APR_HAS_LARGE_FILES
         overlapped.OffsetHigh = (DWORD)(curoff >> 32);
 #endif
-        /* XXX BoundsChecker claims dwFlags must not be zero. */
         rv = TransmitFile(sock->socketdes,  /* socket */
                           file->filehand, /* open file descriptor of the file 
to be sent */
                           nbytes,         /* number of bytes to send. 0=send 
all */



Reply via email to