From dev-return-20138-apmail-apr-dev-archive=apr.apache.org@apr.apache.org Wed May 14 18:15:59 2008 Return-Path: Delivered-To: apmail-apr-dev-archive@www.apache.org Received: (qmail 48615 invoked from network); 14 May 2008 18:15:59 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 14 May 2008 18:15:59 -0000 Received: (qmail 80880 invoked by uid 500); 14 May 2008 18:15:59 -0000 Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 80818 invoked by uid 500); 14 May 2008 18:15:59 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Id: Delivered-To: mailing list dev@apr.apache.org Received: (qmail 80799 invoked by uid 99); 14 May 2008 18:15:59 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 14 May 2008 11:15:59 -0700 X-ASF-Spam-Status: No, hits=1.2 required=10.0 tests=SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (athena.apache.org: local policy) Received: from [64.202.165.233] (HELO smtpout07.prod.mesa1.secureserver.net) (64.202.165.233) by apache.org (qpsmtpd/0.29) with SMTP; Wed, 14 May 2008 18:15:12 +0000 Received: (qmail 23877 invoked from network); 14 May 2008 18:15:24 -0000 Received: from unknown (71.239.140.137) by smtpout07-04.prod.mesa1.secureserver.net (64.202.165.233) with ESMTP; 14 May 2008 18:15:24 -0000 Message-ID: <482B2C3B.2080207@rowe-clan.net> Date: Wed, 14 May 2008 13:15:23 -0500 From: "William A. Rowe, Jr." User-Agent: Thunderbird 2.0.0.14 (X11/20080501) MIME-Version: 1.0 To: Jim Jagielski CC: APR Developer List Subject: Re: sendfile in darwin References: <2EA94233-5650-4168-9071-EE9B4B451C86@jaguNET.com> <3B4823DC-C723-47C8-85F6-01C25947728D@jaguNET.com> <827F5091-3959-41C0-8286-777AA3643885@jaguNET.com> <7D1DBBCE-871D-44ED-A6EC-8B9105C6C3E2@jaguNET.com> <9E084011-40B5-4906-9507-36BDDE2C0852@webweaving.org> <4B83778A-75C2-44B7-8670-D4C6085854BD@jagunet.com> <20080507185847.GG32380@cr> <6E447C2E-6D85-402B-B312-C7807CA509C1@webweaving.org> <56097.64.172.17.3.1210197491.squirrel@webmail.mipsisrisc.com> <4829E501.6040107@rowe-clan.net> <33394790-5F9B-4C1A-8AAE-ED06A84D23DD@jagunet.com> <482B1D7C.701@rowe-clan.net> <8E6C31A1-6CBD-4219-ADCE-080F56C36514@jagunet.com> <482B26F8.40107@rowe-clan.net> <209DC065-2D5F-423A-A3F6-7E5673551332@jagunet.com> In-Reply-To: <209DC065-2D5F-423A-A3F6-7E5673551332@jagunet.com> X-Enigmail-Version: 0.95.6 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org Corrupt patch, would you mind resending at a text/plain attach? Jim Jagielski wrote: > > On May 14, 2008, at 1:52 PM, William A. Rowe, Jr. wrote: > >> Jim Jagielski wrote: >>> I'll have to try that... in the meantime, does re-adding >>> the 'rv=0' line fix it? >> >> With flying colors. Yes. >> > > But I'm guessing it dies with the httpd test framework. > > Can you try with the below patch: > > Index: network_io/unix/sendrecv.c > =================================================================== > --- network_io/unix/sendrecv.c (revision 656320) > +++ network_io/unix/sendrecv.c (working copy) > @@ -406,15 +406,15 @@ > #elif defined(DARWIN) > > /* OS/X Release 10.5 or greater */ > -apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file, > - apr_hdtr_t * hdtr, apr_off_t * offset, > - apr_size_t * len, apr_int32_t flags) > +apr_status_t apr_socket_sendfile(apr_socket_t *sock, apr_file_t *file, > + apr_hdtr_t *hdtr, apr_off_t *offset, > + apr_size_t *len, apr_int32_t flags) > { > apr_off_t nbytes = 0; > apr_off_t bytes_to_send = *len; > - apr_size_t header_bytes_written = 0; > + apr_off_t bytes_sent = 0; > + apr_status_t arv; > int rv = 0; > - int sent_headers = 0; > > /* Ignore flags for now. */ > flags = 0; > @@ -425,8 +425,31 @@ > > /* OS X can send the headers/footers as part of the system call, > * but how it counts bytes isn't documented properly. We use > - * writev() instead. > + * apr_socket_sendv() instead. > */ > + if (hdtr->numheaders > 0) { > + apr_size_t hbytes; > + int i; > + > + /* Now write the headers */ > + arv = apr_socket_sendv(sock, hdtr->headers, hdtr->numheaders, > + &hbytes); > + if (arv != APR_SUCCESS) { > + *len = 0; > + return errno; > + } > + bytes_sent = hbytes; > + > + hbytes = 0; > + for (i = 0; i < hdtr->numheaders; i++) { > + hbytes += hdtr->headers[i].iov_len; > + } > + if (bytes_sent < hbytes) { > + *len = bytes_sent; > + return APR_SUCCESS; > + } > + } > + > do { > if (sock->options & APR_INCOMPLETE_WRITE) { > apr_status_t arv; > @@ -438,72 +461,37 @@ > } > } > > - if (!sent_headers) { > - if (hdtr->numheaders) { > - rv = writev(sock->socketdes, > - hdtr->headers, > - hdtr->numheaders); > - if (rv > 0) { > - header_bytes_written = rv; > - sent_headers = 1; > - rv = 0; > - } > - } > - else { > - sent_headers = 1; > - } > - } > + nbytes = bytes_to_send; > + 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 */ > + NULL, /* Headers/footers */ > + flags); /* undefined, set to 0 */ > > - if (bytes_to_send && sent_headers) { > - /* 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. > - */ > - nbytes = bytes_to_send; > - 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 */ > - NULL, /* Headers/footers */ > - flags); /* undefined, set to 0 */ > - > - bytes_to_send -= nbytes; > - if (rv == -1) { > - if (errno == EAGAIN) { > - if (sock->timeout > 0) { > - sock->options |= APR_INCOMPLETE_WRITE; > - } > - /* 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. > - */ > - else if (nbytes) { > - /* normal exit for a big file & non-blocking io */ > - (*len) = nbytes + header_bytes_written; > - return APR_SUCCESS; > - } > + bytes_sent += nbytes; > + bytes_to_send -= nbytes; > + (*offset) += nbytes; > + if (rv == -1) { > + if (errno == EAGAIN) { > + if (sock->timeout > 0) { > + sock->options |= APR_INCOMPLETE_WRITE; > } > - } > - else { /* rv == 0 (or the kernel is broken) */ > - if (nbytes == 0) { > - /* Most likely the file got smaller after the stat. > - * Return an error so the caller can do the Right > Thing. > - */ > - (*len) = nbytes + header_bytes_written; > - return APR_EOF; > + /* 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. > + */ > + else if (nbytes) { > + /* normal exit for a big file & non-blocking io */ > + (*len) = bytes_sent; > + return APR_SUCCESS; > } > } > } > - > - if (sent_headers && !bytes_to_send) { > - /* just trailer bytes... use writev() > - */ > - rv = writev(sock->socketdes, > - hdtr->trailers, > - hdtr->numtrailers); > - if (rv > 0) { > - nbytes += rv; > - rv = 0; > + else { /* rv == 0 (or the kernel is broken) */ > + if (nbytes == 0) { > + (*len) = bytes_sent; > + return APR_SUCCESS; > } > } > > @@ -512,7 +500,20 @@ > } > } while (rv == -1 && (errno == EINTR || errno == EAGAIN)); > > - (*len) = nbytes + header_bytes_written; > + /* Now write the footers */ > + if (hdtr->numtrailers > 0) { > + apr_size_t tbytes; > + arv = apr_socket_sendv(sock, hdtr->trailers, hdtr->numtrailers, > + &tbytes); > + bytes_sent += tbytes; > + if (arv != APR_SUCCESS) { > + *len = bytes_sent; > + rv = errno; > + return rv; > + } > + } > + > + (*len) = bytes_sent; > if (rv == -1) { > return errno; > } > > > >