William A. Rowe, Jr. wrote:
At 10:48 AM 8/3/2005, Phillip Susi wrote:
William A. Rowe, Jr. wrote:
In the APR library, yes, we translate 'apr_sendfile' to TransmitFile()
on win32. Some other magic occurs to obtain a file handle which can be passed
to TransmitFile. But there are enough flaws in the TF() api
that perhaps this would be better defaulted to 'off'.
Really? Are you quite sure? I wonder what's hosing it all up. Once you hand TransmitFile() the socket and file handles, it should blast the file over the network nice and fast.
Yes of course :) However, sadly, Microsoft has a number of bugs
Search the archives of this or the apr mailing list... other than bugs (which can be reported to MS with
reasonable expectation that they will be fixed. maybe :-), the most serious flaw is that there is no way to
timeout calls to TransmitFile. If I call TransmitFile to send a file and the client chooses to not read any
of the bytes I send him, transmitfile will fill-up the send buffers in the TCP stack then block forever. I've
never found a way to check the 'status' of the call to TransmitFile, to see if it was making 'acceptable'
progress sending bytes to the client.
To solve (by some definition of solve) this timeout problem, we made TransmitFile (under apr_sendfile) send no
more than 64K bytes at a time. The call to transmitfile is non-blocking and the calling thread blocks on
WaitForSingleObject for 'timeout' seconds. If the call completes before the WaitFor call times out, we send
the next 64K byte chunk of the file. Repeat until all the file is sent. Whoever came up with the brilliant
idea of making multiple calls to TransmitFile to send files over 64K bytes needs to be dragged behind a bus ;-)
Now if Apache 2 supported asynchronous (or event driven) writes to the network (like IIS), we could just call
apr_sendfile/TransmitFile once to send the whole shaboozie and not worry (too much) about whether the client
is broken or is running a DoS attack. A monitor thread would periodically check for a transmitfile completion
status; if the completion status is too slow in coming, the monitor thread cancels the io and closes the socket.