[nginx] Moved writev() handling code to a separate function.

Valentin Bartenev vbart at nginx.com
Wed Nov 19 18:19:12 UTC 2014


details:   http://hg.nginx.org/nginx/rev/2c64b69daec5
branches:  
changeset: 5917:2c64b69daec5
user:      Valentin Bartenev <vbart at nginx.com>
date:      Wed Aug 13 15:11:45 2014 +0400
description:
Moved writev() handling code to a separate function.

This reduces code duplication and unifies debug logging of the writev() syscall
among various send chain functions.

diffstat:

 src/os/unix/ngx_darwin_sendfile_chain.c  |  29 ++----------
 src/os/unix/ngx_freebsd_sendfile_chain.c |  29 ++----------
 src/os/unix/ngx_linux_sendfile_chain.c   |  28 ++----------
 src/os/unix/ngx_os.h                     |   3 +
 src/os/unix/ngx_writev_chain.c           |  73 ++++++++++++++++++-------------
 5 files changed, 60 insertions(+), 102 deletions(-)

diffs (268 lines):

diff -r e044893b4587 -r 2c64b69daec5 src/os/unix/ngx_darwin_sendfile_chain.c
--- a/src/os/unix/ngx_darwin_sendfile_chain.c	Wed Aug 13 15:11:45 2014 +0400
+++ b/src/os/unix/ngx_darwin_sendfile_chain.c	Wed Aug 13 15:11:45 2014 +0400
@@ -33,6 +33,7 @@ ngx_darwin_sendfile_chain(ngx_connection
     int              rc;
     off_t            send, prev_send, sent;
     off_t            file_size;
+    ssize_t          n;
     ngx_uint_t       eintr;
     ngx_err_t        err;
     ngx_buf_t       *file;
@@ -172,33 +173,13 @@ ngx_darwin_sendfile_chain(ngx_connection
                            rc, file->file_pos, sent, file_size + header.size);
 
         } else {
-            rc = writev(c->fd, header.iovs, header.count);
+            n = ngx_writev(c, &header);
 
-            ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                           "writev: %d of %uz", rc, header.size);
-
-            if (rc == -1) {
-                err = ngx_errno;
-
-                switch (err) {
-                case NGX_EAGAIN:
-                    break;
-
-                case NGX_EINTR:
-                    eintr = 1;
-                    break;
-
-                default:
-                    wev->error = 1;
-                    ngx_connection_error(c, err, "writev() failed");
-                    return NGX_CHAIN_ERROR;
-                }
-
-                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
-                               "writev() not ready");
+            if (n == NGX_ERROR) {
+                return NGX_CHAIN_ERROR;
             }
 
-            sent = rc > 0 ? rc : 0;
+            sent = (n == NGX_AGAIN) ? 0 : n;
         }
 
         c->sent += sent;
diff -r e044893b4587 -r 2c64b69daec5 src/os/unix/ngx_freebsd_sendfile_chain.c
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c	Wed Aug 13 15:11:45 2014 +0400
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c	Wed Aug 13 15:11:45 2014 +0400
@@ -35,6 +35,7 @@ ngx_freebsd_sendfile_chain(ngx_connectio
     int              rc, flags;
     off_t            send, prev_send, sent;
     size_t           file_size;
+    ssize_t          n;
     ngx_uint_t       eintr, eagain;
     ngx_err_t        err;
     ngx_buf_t       *file;
@@ -217,33 +218,13 @@ ngx_freebsd_sendfile_chain(ngx_connectio
                            rc, file->file_pos, sent, file_size + header.size);
 
         } else {
-            rc = writev(c->fd, header.iovs, header.count);
+            n = ngx_writev(c, &header);
 
-            ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                           "writev: %d of %uz", rc, header.size);
-
-            if (rc == -1) {
-                err = ngx_errno;
-
-                switch (err) {
-                case NGX_EAGAIN:
-                    break;
-
-                case NGX_EINTR:
-                    eintr = 1;
-                    break;
-
-                default:
-                    wev->error = 1;
-                    ngx_connection_error(c, err, "writev() failed");
-                    return NGX_CHAIN_ERROR;
-                }
-
-                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
-                               "writev() not ready");
+            if (n == NGX_ERROR) {
+                return NGX_CHAIN_ERROR;
             }
 
-            sent = rc > 0 ? rc : 0;
+            sent = (n == NGX_AGAIN) ? 0 : n;
         }
 
         c->sent += sent;
diff -r e044893b4587 -r 2c64b69daec5 src/os/unix/ngx_linux_sendfile_chain.c
--- a/src/os/unix/ngx_linux_sendfile_chain.c	Wed Aug 13 15:11:45 2014 +0400
+++ b/src/os/unix/ngx_linux_sendfile_chain.c	Wed Aug 13 15:11:45 2014 +0400
@@ -33,6 +33,7 @@ ngx_linux_sendfile_chain(ngx_connection_
     int            rc, tcp_nodelay;
     off_t          send, prev_send, sent;
     size_t         file_size;
+    ssize_t        n;
     ngx_err_t      err;
     ngx_buf_t     *file;
     ngx_uint_t     eintr;
@@ -199,32 +200,13 @@ ngx_linux_sendfile_chain(ngx_connection_
                            rc, file->file_pos, sent, file_size);
 
         } else {
-            rc = writev(c->fd, header.iovs, header.count);
+            n = ngx_writev(c, &header);
 
-            if (rc == -1) {
-                err = ngx_errno;
-
-                switch (err) {
-                case NGX_EAGAIN:
-                    break;
-
-                case NGX_EINTR:
-                    eintr = 1;
-                    break;
-
-                default:
-                    wev->error = 1;
-                    ngx_connection_error(c, err, "writev() failed");
-                    return NGX_CHAIN_ERROR;
-                }
-
-                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
-                               "writev() not ready");
+            if (n == NGX_ERROR) {
+                return NGX_CHAIN_ERROR;
             }
 
-            sent = rc > 0 ? rc : 0;
-
-            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %O", sent);
+            sent = (n == NGX_AGAIN) ? 0 : n;
         }
 
         c->sent += sent;
diff -r e044893b4587 -r 2c64b69daec5 src/os/unix/ngx_os.h
--- a/src/os/unix/ngx_os.h	Wed Aug 13 15:11:45 2014 +0400
+++ b/src/os/unix/ngx_os.h	Wed Aug 13 15:11:45 2014 +0400
@@ -75,6 +75,9 @@ ngx_chain_t *ngx_output_chain_to_iovec(n
     size_t limit, ngx_log_t *log);
 
 
+ssize_t ngx_writev(ngx_connection_t *c, ngx_iovec_t *vec);
+
+
 extern ngx_os_io_t  ngx_os_io;
 extern ngx_int_t    ngx_ncpu;
 extern ngx_int_t    ngx_max_sockets;
diff -r e044893b4587 -r 2c64b69daec5 src/os/unix/ngx_writev_chain.c
--- a/src/os/unix/ngx_writev_chain.c	Wed Aug 13 15:11:45 2014 +0400
+++ b/src/os/unix/ngx_writev_chain.c	Wed Aug 13 15:11:45 2014 +0400
@@ -15,8 +15,6 @@ ngx_writev_chain(ngx_connection_t *c, ng
 {
     ssize_t        n, sent;
     off_t          send, prev_send;
-    ngx_uint_t     eintr;
-    ngx_err_t      err;
     ngx_chain_t   *cl;
     ngx_event_t   *wev;
     ngx_iovec_t    vec;
@@ -51,7 +49,6 @@ ngx_writev_chain(ngx_connection_t *c, ng
     vec.nalloc = NGX_IOVS_PREALLOCATE;
 
     for ( ;; ) {
-        eintr = 0;
         prev_send = send;
 
         /* create the iovec and coalesce the neighbouring bufs */
@@ -83,42 +80,18 @@ ngx_writev_chain(ngx_connection_t *c, ng
 
         send += vec.size;
 
-        n = writev(c->fd, vec.iovs, vec.count);
+        n = ngx_writev(c, &vec);
 
-        if (n == -1) {
-            err = ngx_errno;
-
-            switch (err) {
-            case NGX_EAGAIN:
-                break;
-
-            case NGX_EINTR:
-                eintr = 1;
-                break;
-
-            default:
-                wev->error = 1;
-                (void) ngx_connection_error(c, err, "writev() failed");
-                return NGX_CHAIN_ERROR;
-            }
-
-            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
-                           "writev() not ready");
+        if (n == NGX_ERROR) {
+            return NGX_CHAIN_ERROR;
         }
 
-        sent = n > 0 ? n : 0;
-
-        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %z", sent);
+        sent = (n == NGX_AGAIN) ? 0 : n;
 
         c->sent += sent;
 
         in = ngx_chain_update_sent(in, sent);
 
-        if (eintr) {
-            send = prev_send;
-            continue;
-        }
-
         if (send - prev_send != sent) {
             wev->ready = 0;
             return in;
@@ -203,3 +176,41 @@ ngx_output_chain_to_iovec(ngx_iovec_t *v
 
     return in;
 }
+
+
+ssize_t
+ngx_writev(ngx_connection_t *c, ngx_iovec_t *vec)
+{
+    ssize_t    n;
+    ngx_err_t  err;
+
+eintr:
+
+    n = writev(c->fd, vec->iovs, vec->count);
+
+    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                   "writev: %z of %uz", n, vec->size);
+
+    if (n == -1) {
+        err = ngx_errno;
+
+        switch (err) {
+        case NGX_EAGAIN:
+            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+                           "writev() not ready");
+            return NGX_AGAIN;
+
+        case NGX_EINTR:
+            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+                           "writev() was interrupted");
+            goto eintr;
+
+        default:
+            c->write->error = 1;
+            ngx_connection_error(c, err, "writev() failed");
+            return NGX_ERROR;
+        }
+    }
+
+    return n;
+}



More information about the nginx-devel mailing list