Welcome! Log In Create A New Profile

Advanced

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

Valentin Bartenev
November 19, 2014 01:20PM
details: http://hg.nginx.org/nginx/rev/2c64b69daec5
branches:
changeset: 5917:2c64b69daec5
user: Valentin Bartenev <vbart@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;
+}

_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

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

Valentin Bartenev 687 November 19, 2014 01:20PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 243
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready