dev  

Re: sendfile in darwin

Jim Jagielski
Wed, 07 May 2008 11:43:22 -0700


On May 7, 2008, at 2:31 PM, Dirk-Willem van Gulik wrote:

Hmm - Jim - that does not quite solve the issue I was discussing on IRC;

On IRC? What happened to onlist discussions?? :)

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 ?


This looks like a patch on something that already patches
things... so I can't comment on whether this makes sense since
it includes a patch which I have no clue about.

The addition of 'rv = 0' though on line ~453 is almost
for sure wrong...


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