You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Bill Stoddard <bi...@wstoddard.com> on 2004/04/12 18:14:32 UTC

Re: Performance of TransmitFile on Windows Servers with 2.0.49

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 */