diff src/os/unix/ngx_freebsd_sendfile_chain.c @ 362:7650aea1816f

nginx-0.0.7-2004-06-21-19:59:32 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 21 Jun 2004 15:59:32 +0000
parents 446782c909b3
children 744ccb59062d
line wrap: on
line diff
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -28,21 +28,22 @@
  */
 
 
-ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
+ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
+                                        off_t limit)
 {
     int              rc;
     u_char          *prev;
-    off_t            sent, fprev, send, limit;
+    off_t            fprev, sent, send, sprev, aligned;
     size_t           hsize, fsize;
     ssize_t          size;
-    ngx_uint_t       eintr, eagain, ready;
+    ngx_uint_t       eintr, eagain, complete;
     struct iovec    *iov;
     struct sf_hdtr   hdtr;
     ngx_err_t        err;
     ngx_buf_t       *file;
     ngx_array_t      header, trailer;
     ngx_event_t     *wev;
-    ngx_chain_t     *cl, *tail;
+    ngx_chain_t     *cl;
 
     wev = c->write;
 
@@ -62,20 +63,16 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
 
 #endif
 
-#if 1
-    limit = 4096;
-#else
-    limit = OFF_T_MAX_VALUE;
-#endif
+    send = 0;
+    eagain = 0;
 
-    do {
+    for ( ;; ) {
         file = NULL;
         fsize = 0;
         hsize = 0;
-        send = 0;
         eintr = 0;
-        eagain = 0;
-        ready = 0;
+        complete = 0;
+        sprev = send;
 
         ngx_init_array(header, c->pool, 10, sizeof(struct iovec),
                        NGX_CHAIN_ERROR);
@@ -87,7 +84,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
         prev = NULL;
         iov = NULL;
 
-        for (cl = in; cl && header.nelts < IOV_MAX; cl = cl->next) {
+        for (cl = in;
+             cl && header.nelts < IOV_MAX && send < limit;
+             cl = cl->next)
+        {
             if (ngx_buf_special(cl->buf)) {
                 continue;
             }
@@ -118,7 +118,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
 
         /* get the file buf */
 
-        if (cl && cl->buf->in_file) {
+        if (cl && cl->buf->in_file && send < limit) {
             file = cl->buf;
             fsize = 0;
 
@@ -129,6 +129,13 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
 
                 if (send + size > limit) {
                     size = limit - send;
+
+                    aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
+                                                      & ~(ngx_pagesize - 1);
+
+                    if (aligned <= cl->buf->file_last) {
+                        size = aligned - cl->buf->file_pos;
+                    }
                 }
 
                 fsize += size;
@@ -138,6 +145,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
 
             } while (cl
                      && cl->buf->in_file
+                     && send < limit
                      && file->file->fd == cl->buf->file->fd
                      && fprev == cl->buf->file_pos);
         }
@@ -148,7 +156,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
             prev = NULL;
             iov = NULL;
 
-            for ( /* void */; cl && trailer.nelts < IOV_MAX; cl = cl->next) {
+            for (/* void */;
+                 cl && header.nelts < IOV_MAX && send < limit;
+                 cl = cl->next)
+            {
                 if (ngx_buf_special(cl->buf)) {
                     continue;
                 }
@@ -178,13 +189,6 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
             }
         }
 
-        /*
-         * the tail is the rest of the chain that exceedes
-         * a single sendfile() capability
-         */
-
-        tail = cl;
-
         if (file) {
 
             if (ngx_freebsd_use_tcp_nopush
@@ -286,8 +290,8 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
             sent = rc > 0 ? rc : 0;
         }
 
-        if (send == sent) {
-            ready = 1;
+        if (send - sprev == sent) {
+            complete = 1;
         }
 
         c->sent += sent;
@@ -329,12 +333,6 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
             break;
         }
 
-        if (ready) {
-            return cl;
-        }
-
-        in = cl;
-
         if (eagain) {
 
             /*
@@ -345,16 +343,22 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
              */
 
             wev->ready = 0;
-            break;
+            return cl;
+        }
+
+        if (eintr) {
+            continue;
         }
 
-        /* "tail == in" means that a single sendfile() is complete */
-
-    } while ((tail && tail == in) || eintr);
+        if (!complete) {
+            wev->ready = 0;
+            return cl;
+        }
 
-    if (in) {
-        wev->ready = 0;
+        if (send >= limit || cl == NULL) {
+            return cl;
+        }
+
+        in = cl;
     }
-
-    return in;
 }