[prev in list] [next in list] [prev in thread] [next in thread] 

List:       apr-cvs
Subject:    svn commit: r651395 - in /apr/apr/trunk: CHANGES network_io/unix/sendrecv.c
From:       wrowe () apache ! org
Date:       2008-04-24 20:26:02
Message-ID: 20080424202604.56D441A9832 () eris ! apache ! org
[Download RAW message or body]

Author: wrowe
Date: Thu Apr 24 13:25:55 2008
New Revision: 651395

URL: http://svn.apache.org/viewvc?rev=651395&view=rev
Log:
Support OS/X sendfile by using writev rather than the miscounted sendfile's
hdtr iovecs.

Submitted by: Geoff Greer <angryparsley mipsisrisc.com>

Modified:
    apr/apr/trunk/CHANGES
    apr/apr/trunk/network_io/unix/sendrecv.c

Modified: apr/apr/trunk/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/trunk/CHANGES?rev=651395&r1=651394&r2=651395&view=diff
 ==============================================================================
--- apr/apr/trunk/CHANGES [utf-8] (original)
+++ apr/apr/trunk/CHANGES [utf-8] Thu Apr 24 13:25:55 2008
@@ -11,6 +11,9 @@
 
 Changes for APR 1.3.0
 
+  *) Support OS/X sendfile by using writev in lieu of hdtr vecs
+     miscounted by the OS.  [Geoff Greer <angryparsley mipsisrisc.com>]
+
   *) Introduce apr_pool_pre_cleanup_register() for registering
      a cleanup that is called before any subpool is destroyed
      within apr_pool_clear or apr_pool_destroy.

Modified: apr/apr/trunk/network_io/unix/sendrecv.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/network_io/unix/sendrecv.c?rev=651395&r1=651394&r2=651395&view=diff
 ==============================================================================
--- apr/apr/trunk/network_io/unix/sendrecv.c (original)
+++ apr/apr/trunk/network_io/unix/sendrecv.c Thu Apr 24 13:25:55 2008
@@ -411,8 +411,9 @@
                                  apr_size_t * len, apr_int32_t flags)
 {
     apr_off_t nbytes = *len;
+    apr_off_t bytes_to_send = *len;
+    apr_size_t header_bytes_written = 0;
     int rv;
-    struct sf_hdtr headerstruct;
 
     /* Ignore flags for now. */
     flags = 0;
@@ -421,12 +422,10 @@
         hdtr = &no_hdtr;
     }
 
-    headerstruct.headers = hdtr->headers;
-    headerstruct.hdr_cnt = hdtr->numheaders;
-    headerstruct.trailers = hdtr->trailers;
-    headerstruct.trl_cnt = hdtr->numtrailers;
-
-    /* BSD can send the headers/footers as part of the system call */
+    /* 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.
+     */
     do {
         if (sock->options & APR_INCOMPLETE_WRITE) {
             apr_status_t arv;
@@ -437,18 +436,33 @@
                 return arv;
             }
         }
-        if (nbytes) {
+        
+        if (hdtr->numheaders) {
+            rv = writev(sock->socketdes,
+                        hdtr->headers,
+                        hdtr->numheaders);
+            if (rv > 0) {
+                header_bytes_written = rv;
+                rv = 0;
+            }
+            else {
+                header_bytes_written = 0;
+            }
+        }
+        else if (bytes_to_send) {
             /* 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 */
-                          &headerstruct, /* Headers/footers */
+                          NULL,          /* Headers/footers */
                           flags);        /* undefined, set to 0 */
 
+            bytes_to_send -= nbytes;
             if (rv == -1) {
                 if (errno == EAGAIN) {
                     if (sock->timeout > 0) {
@@ -460,7 +474,7 @@
                      */
                     if (nbytes) {
                         /* normal exit for a big file & non-blocking io */
-                        (*len) = nbytes;
+                        (*len) = nbytes + header_bytes_written;
                         return APR_SUCCESS;
                     }
                 }
@@ -470,11 +484,11 @@
                     /* Most likely the file got smaller after the stat.
                      * Return an error so the caller can do the Right Thing.
                      */
-                    (*len) = nbytes;
+                    (*len) = nbytes + header_bytes_written;
                     return APR_EOF;
                 }
             }
-        }    
+        }
         else {
             /* just trailer bytes... use writev()
              */


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic