dev  

Re: sendfile in darwin

Dirk-Willem van Gulik
Wed, 07 May 2008 11:32:30 -0700

Hmm - Jim - that does not quite solve the issue I was discussing on IRC; I think below is needed (which does solve the TimeOut issue).

--> diff with your version -- anticipate nbytes set to 0 (which has whole file semantics on BSD and Darwin).

Does that make sense ?

Dw

Index: network_io/unix/sendrecv.c
===================================================================
--- network_io/unix/sendrecv.c  (revision 648693)
+++ network_io/unix/sendrecv.c  (working copy)
@@ -438,6 +438,7 @@
             }
         }
         if (nbytes) {
+           int nnbytes = nbytes;
             /* We won't dare call sendfile() if we don't have
              * header or file bytes to send because nbytes == 0
              * means send the remaining file to EOF.
@@ -445,7 +446,7 @@
             rv = sendfile(file->filedes, /* file to be sent */
                           sock->socketdes, /* socket */
*offset, /* where in the file to start */ - &nbytes, /* number of bytes to write/ written */ + &nnbytes, /* number of bytes to write/ written */
                           &headerstruct, /* Headers/footers */
                           flags);        /* undefined, set to 0 */

@@ -453,12 +454,13 @@
                 if (errno == EAGAIN) {
                     if (sock->timeout > 0) {
                         sock->options |= APR_INCOMPLETE_WRITE;
+                       rv = 0;
                     }
                     /* BSD's sendfile can return -1/EAGAIN even if it
* sent bytes. Sanitize the result so we get normal EAGAIN
                      * semantics w.r.t. bytes sent.
                      */
-                    if (nbytes) {
+                    if (nnbytes) {
/* normal exit for a big file & non-blocking io */
                         (*len) = nbytes;
                         return APR_SUCCESS;
@@ -466,7 +468,7 @@
                 }
             }
             else {       /* rv == 0 (or the kernel is broken) */
-                if (nbytes == 0) {
+                if (nnbytes == 0) {
/* Most likely the file got smaller after the stat. * Return an error so the caller can do the Right Thing.
                      */