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.

Reply via email to