summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-08-31 11:32:23 +0000
committerJonathan Kolb <jon@b0g.us>2009-08-31 11:32:23 +0000
commit65393e7df3390a8694855748788ffabd4572939b (patch)
tree2b46cf28ba85a28be96e0ad13e362dcadd7f4e0c
parent802fd20929172c84d0fae425d432cb4113b61708 (diff)
downloadnginx-0.8.12.tar.gz
Changes with nginx 0.8.12 31 Aug 2009v0.8.12
*) Feature: the "sendfile" parameter in the "aio" directive on FreeBSD. *) Bugfix: in try_files; the bug had appeared in 0.8.11. *) Bugfix: in memcached; the bug had appeared in 0.8.11.
-rw-r--r--CHANGES13
-rw-r--r--CHANGES.ru15
-rw-r--r--auto/os/freebsd6
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_connection.h5
-rw-r--r--src/event/ngx_event.h4
-rw-r--r--src/http/modules/ngx_http_memcached_module.c2
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http.h6
-rw-r--r--src/http/ngx_http_copy_filter_module.c68
-rw-r--r--src/http/ngx_http_core_module.c23
-rw-r--r--src/http/ngx_http_core_module.h5
-rw-r--r--src/http/ngx_http_postpone_filter_module.c2
-rw-r--r--src/http/ngx_http_request.c20
-rw-r--r--src/http/ngx_http_request.h31
-rw-r--r--src/os/unix/ngx_darwin_sendfile_chain.c40
-rw-r--r--src/os/unix/ngx_file_aio_read.c6
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c57
-rw-r--r--src/os/unix/ngx_linux_sendfile_chain.c34
-rw-r--r--src/os/unix/ngx_solaris_sendfilev_chain.c17
-rw-r--r--src/os/unix/ngx_writev_chain.c17
21 files changed, 279 insertions, 98 deletions
diff --git a/CHANGES b/CHANGES
index 0f994e7f5..d1c8a6234 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,17 @@
+Changes with nginx 0.8.12 31 Aug 2009
+
+ *) Feature: the "sendfile" parameter in the "aio" directive on FreeBSD.
+
+ *) Bugfix: in try_files; the bug had appeared in 0.8.11.
+
+ *) Bugfix: in memcached; the bug had appeared in 0.8.11.
+
+
Changes with nginx 0.8.11 28 Aug 2009
- *) Change: directive "gzip_disable msie6" enables gzipping for
- MSIE 6.0 SV1.
+ *) Change: now directive "gzip_disable msie6" does not disable gzipping
+ for MSIE 6.0 SV1.
*) Feature: file AIO support on FreeBSD and Linux.
diff --git a/CHANGES.ru b/CHANGES.ru
index 566cb8b7a..a037b3ebb 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,8 +1,19 @@
+Изменения в nginx 0.8.12 31.08.2009
+
+ *) Добавление: параметр sendfile в директиве aio во FreeBSD.
+
+ *) Исправление: ошибки при использовании try_files; ошибка появилась в
+ 0.8.11.
+
+ *) Исправление: ошибки при использовании memcached; ошибка появилась в
+ 0.8.11.
+
+
Изменения в nginx 0.8.11 28.08.2009
- *) Изменение: директива "gzip_disable msie6" разрешает сжатие для
- MSIE 6.0 SV1.
+ *) Изменение: теперь директива "gzip_disable msie6" не запрещает сжатие
+ для MSIE 6.0 SV1.
*) Добавление: поддержка файлового AIO во FreeBSD и Linux.
diff --git a/auto/os/freebsd b/auto/os/freebsd
index 596aaa067..20985294f 100644
--- a/auto/os/freebsd
+++ b/auto/os/freebsd
@@ -43,6 +43,12 @@ if [ $osreldate -gt 300007 ]; then
CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
fi
+if [ $osreldate -gt 502103 ]; then
+ echo " + sendfile()'s SF_NODISKIO found"
+
+ have=NGX_HAVE_AIO_SENDFILE . auto/have
+fi
+
# kqueue
diff --git a/src/core/nginx.h b/src/core/nginx.h
index f693e9aab..bfd252d21 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 8011
-#define NGINX_VERSION "0.8.11"
+#define nginx_version 8012
+#define NGINX_VERSION "0.8.12"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index 689b5f0e9..ebc0c4c14 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -159,6 +159,11 @@ struct ngx_connection_s {
unsigned accept_context_updated:1;
#endif
+#if (NGX_HAVE_AIO_SENDFILE)
+ unsigned aio_sendfile:1;
+ ngx_buf_t *busy_sendfile;
+#endif
+
#if (NGX_THREADS)
ngx_atomic_t lock;
#endif
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index ab38546a0..778da529d 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -209,6 +209,10 @@ struct ngx_event_aio_s {
size_t nbytes;
#endif
+#if (NGX_HAVE_AIO_SENDFILE)
+ off_t last_offset;
+#endif
+
ngx_aiocb_t aiocb;
ngx_event_t event;
};
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index dc7c76719..6cf58815b 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -211,6 +211,8 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
u->input_filter = ngx_http_memcached_filter;
u->input_filter_ctx = ctx;
+ r->main->count++;
+
ngx_http_upstream_init(r);
return NGX_DONE;
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 0f185a331..6089126bd 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.8.11';
+our $VERSION = '0.8.12';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 9444b1131..5519a5b85 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -84,13 +84,17 @@ ngx_int_t ngx_http_find_server_conf(ngx_http_request_t *r);
void ngx_http_update_location_config(ngx_http_request_t *r);
void ngx_http_handler(ngx_http_request_t *r);
void ngx_http_run_posted_requests(ngx_connection_t *c);
-ngx_int_t ngx_http_post_request(ngx_http_request_t *r);
+ngx_int_t ngx_http_post_request(ngx_http_request_t *r,
+ ngx_http_posted_request_t *pr);
void ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
void ngx_http_empty_handler(ngx_event_t *wev);
void ngx_http_request_empty_handler(ngx_http_request_t *r);
+#define ngx_http_ephemeral(r) (ngx_http_ephemeral_t *) (&r->uri_start)
+
+
#define NGX_HTTP_LAST 1
#define NGX_HTTP_FLUSH 2
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
index 5587ba447..f3d0f1161 100644
--- a/src/http/ngx_http_copy_filter_module.c
+++ b/src/http/ngx_http_copy_filter_module.c
@@ -18,6 +18,9 @@ typedef struct {
static void ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx,
ngx_file_t *file);
static void ngx_http_copy_aio_event_handler(ngx_event_t *ev);
+#if (NGX_HAVE_AIO_SENDFILE)
+static void ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev);
+#endif
#endif
static void *ngx_http_copy_filter_create_conf(ngx_conf_t *cf);
@@ -89,7 +92,7 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "copy filter: \"%V?%V\"", &r->uri, &r->args);
+ "http copy filter: \"%V?%V\"", &r->uri, &r->args);
ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module);
@@ -121,6 +124,9 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
#if (NGX_HAVE_FILE_AIO)
if (clcf->aio) {
ctx->aio = ngx_http_copy_aio_handler;
+#if (NGX_HAVE_AIO_SENDFILE)
+ c->aio_sendfile = (clcf->aio == NGX_HTTP_AIO_SENDFILE);
+#endif
}
#endif
@@ -136,8 +142,44 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
r->buffered |= NGX_HTTP_COPY_BUFFERED;
}
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args);
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args);
+
+#if (NGX_HAVE_AIO_SENDFILE)
+
+ if (c->busy_sendfile) {
+ off_t offset;
+ ngx_file_t *file;
+ ngx_http_ephemeral_t *e;
+
+ file = c->busy_sendfile->file;
+ offset = c->busy_sendfile->file_pos;
+
+ if (file->aio) {
+ c->aio_sendfile = (offset != file->aio->last_offset);
+ file->aio->last_offset = offset;
+
+ if (c->aio_sendfile == 0) {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+ "sendfile(%V) returned busy again", &file->name);
+ }
+ }
+
+ c->busy_sendfile = NULL;
+ e = (ngx_http_ephemeral_t *) &r->uri_start;
+
+ (void) ngx_file_aio_read(file, e->preload, 4, offset, r->pool);
+
+ if (file->aio) {
+ file->aio->data = r;
+ file->aio->handler = ngx_http_copy_aio_sendfile_event_handler;
+
+ r->main->blocked++;
+ r->aio = 1;
+ }
+ }
+
+#endif
return rc;
}
@@ -175,6 +217,26 @@ ngx_http_copy_aio_event_handler(ngx_event_t *ev)
r->connection->write->handler(r->connection->write);
}
+
+#if (NGX_HAVE_AIO_SENDFILE)
+
+static void
+ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev)
+{
+ ngx_event_aio_t *aio;
+ ngx_http_request_t *r;
+
+ aio = ev->data;
+ r = aio->data;
+
+ r->main->blocked--;
+ r->aio = 0;
+ ev->complete = 0;
+
+ r->connection->write->handler(r->connection->write);
+}
+
+#endif
#endif
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index b9eb0608c..8d83c440e 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -104,6 +104,20 @@ static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = {
};
+#if (NGX_HAVE_FILE_AIO)
+
+static ngx_conf_enum_t ngx_http_core_aio[] = {
+ { ngx_string("off"), NGX_HTTP_AIO_OFF },
+ { ngx_string("on"), NGX_HTTP_AIO_ON },
+#if (NGX_HAVE_AIO_SENDFILE)
+ { ngx_string("sendfile"), NGX_HTTP_AIO_SENDFILE },
+#endif
+ { ngx_null_string, 0 }
+};
+
+#endif
+
+
static ngx_conf_enum_t ngx_http_core_satisfy[] = {
{ ngx_string("all"), NGX_HTTP_SATISFY_ALL },
{ ngx_string("any"), NGX_HTTP_SATISFY_ANY },
@@ -386,11 +400,11 @@ static ngx_command_t ngx_http_core_commands[] = {
#if (NGX_HAVE_FILE_AIO)
{ ngx_string("aio"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_enum_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, aio),
- NULL },
+ &ngx_http_core_aio },
#endif
@@ -1201,6 +1215,7 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
(void) ngx_http_internal_redirect(r, &path, &args);
}
+ ngx_http_finalize_request(r, NGX_DONE);
return NGX_OK;
}
@@ -2139,7 +2154,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
*psr = sr;
- return ngx_http_post_request(sr);
+ return ngx_http_post_request(sr, NULL);
}
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 826b403d6..9946c4f33 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -24,6 +24,11 @@
#define NGX_HTTP_GZIP_PROXIED_ANY 0x0200
+#define NGX_HTTP_AIO_OFF 0
+#define NGX_HTTP_AIO_ON 1
+#define NGX_HTTP_AIO_SENDFILE 2
+
+
#define NGX_HTTP_SATISFY_ALL 0
#define NGX_HTTP_SATISFY_ANY 1
diff --git a/src/http/ngx_http_postpone_filter_module.c b/src/http/ngx_http_postpone_filter_module.c
index 3b1d780f2..156401b32 100644
--- a/src/http/ngx_http_postpone_filter_module.c
+++ b/src/http/ngx_http_postpone_filter_module.c
@@ -102,7 +102,7 @@ ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
c->data = pr->request;
- return ngx_http_post_request(pr->request);
+ return ngx_http_post_request(pr->request, NULL);
}
if (pr->out == NULL) {
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 187310b96..c8976498c 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1810,13 +1810,15 @@ ngx_http_run_posted_requests(ngx_connection_t *c)
ngx_int_t
-ngx_http_post_request(ngx_http_request_t *r)
+ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr)
{
- ngx_http_posted_request_t *pr, **p;
+ ngx_http_posted_request_t **p;
- pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
if (pr == NULL) {
- return NGX_ERROR;
+ pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
+ if (pr == NULL) {
+ return NGX_ERROR;
+ }
}
pr->request = r;
@@ -1965,7 +1967,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
}
}
- if (ngx_http_post_request(pr) != NGX_OK) {
+ if (ngx_http_post_request(pr, NULL) != NGX_OK) {
r->main->count++;
ngx_http_terminate_request(r, 0);
return;
@@ -2025,8 +2027,9 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
static void
ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
{
- ngx_http_cleanup_t *cln;
- ngx_http_request_t *mr;
+ ngx_http_cleanup_t *cln;
+ ngx_http_request_t *mr;
+ ngx_http_ephemeral_t *e;
mr = r->main;
@@ -2054,9 +2057,10 @@ ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
return;
}
+ e = ngx_http_ephemeral(mr);
mr->posted_requests = NULL;
mr->write_event_handler = ngx_http_terminate_handler;
- (void) ngx_http_post_request(mr);
+ (void) ngx_http_post_request(mr, &e->terminal_posted_request);
return;
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 52ac90c23..2ca215377 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -510,6 +510,21 @@ struct ngx_http_request_s {
/* used to parse HTTP headers */
ngx_uint_t state;
+
+ ngx_uint_t header_hash;
+ ngx_uint_t lowcase_index;
+ u_char lowcase_header[NGX_HTTP_LC_HEADER_LEN];
+
+ u_char *header_name_start;
+ u_char *header_name_end;
+ u_char *header_start;
+ u_char *header_end;
+
+ /*
+ * a memory that can be reused after parsing a request line
+ * via ngx_http_ephemeral_t
+ */
+
u_char *uri_start;
u_char *uri_end;
u_char *uri_ext;
@@ -523,20 +538,20 @@ struct ngx_http_request_s {
u_char *host_end;
u_char *port_start;
u_char *port_end;
- u_char *header_name_start;
- u_char *header_name_end;
- u_char *header_start;
- u_char *header_end;
unsigned http_minor:16;
unsigned http_major:16;
-
- ngx_uint_t header_hash;
- ngx_uint_t lowcase_index;
- u_char lowcase_header[NGX_HTTP_LC_HEADER_LEN];
};
+typedef struct {
+ ngx_http_posted_request_t terminal_posted_request;
+#if (NGX_HAVE_AIO_SENDFILE)
+ u_char preload[4];
+#endif
+} ngx_http_ephemeral_t;
+
+
extern ngx_http_header_t ngx_http_headers_in[];
extern ngx_http_header_out_t ngx_http_headers_out[];
diff --git a/src/os/unix/ngx_darwin_sendfile_chain.c b/src/os/unix/ngx_darwin_sendfile_chain.c
index e3ec7f704..59d46534b 100644
--- a/src/os/unix/ngx_darwin_sendfile_chain.c
+++ b/src/os/unix/ngx_darwin_sendfile_chain.c
@@ -42,7 +42,7 @@ ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
u_char *prev;
off_t size, send, prev_send, aligned, sent, fprev;
off_t header_size, file_size;
- ngx_uint_t eintr, eagain, complete;
+ ngx_uint_t eintr, complete;
ngx_err_t err;
ngx_buf_t *file;
ngx_array_t header, trailer;
@@ -75,7 +75,6 @@ ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
}
send = 0;
- eagain = 0;
header.elts = headers;
header.size = sizeof(struct iovec);
@@ -238,22 +237,22 @@ ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
if (rc == -1) {
err = ngx_errno;
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- if (err == NGX_EINTR) {
- eintr = 1;
-
- } else {
- eagain = 1;
- }
+ switch (err) {
+ case NGX_EAGAIN:
+ break;
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
- "sendfile() sent only %O bytes", sent);
+ case NGX_EINTR:
+ eintr = 1;
+ break;
- } else {
+ default:
wev->error = 1;
(void) ngx_connection_error(c, err, "sendfile() failed");
return NGX_CHAIN_ERROR;
}
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "sendfile() sent only %O bytes", sent);
}
if (rc == 0 && sent == 0) {
@@ -284,19 +283,22 @@ ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
if (rc == -1) {
err = ngx_errno;
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- if (err == NGX_EINTR) {
- eintr = 1;
- }
+ switch (err) {
+ case NGX_EAGAIN:
+ break;
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "writev() not ready");
+ case NGX_EINTR:
+ eintr = 1;
+ break;
- } else {
+ 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");
}
sent = rc > 0 ? rc : 0;
diff --git a/src/os/unix/ngx_file_aio_read.c b/src/os/unix/ngx_file_aio_read.c
index bf089ec5d..19a75890c 100644
--- a/src/os/unix/ngx_file_aio_read.c
+++ b/src/os/unix/ngx_file_aio_read.c
@@ -15,7 +15,8 @@
* if an asked data are already in VM cache, then aio_error() returns 0,
* and the data are already copied in buffer;
*
- * aio_read() preread in VM cache as minimum 32K;
+ * aio_read() preread in VM cache as minimum 16K (probably BKVASIZE);
+ * the first AIO preload may be up to 128K;
*
* aio_read/aio_error() may return EINPROGRESS for just written data;
*
@@ -60,6 +61,9 @@ ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
aio->event.data = aio;
aio->event.ready = 1;
aio->event.log = file->log;
+#if (NGX_HAVE_AIO_SENDFILE)
+ aio->last_offset = -1;
+#endif
file->aio = aio;
}
diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
index c383fbeb5..976b6d0b4 100644
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -40,7 +40,7 @@
ngx_chain_t *
ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
{
- int rc;
+ int rc, flags;
u_char *prev;
off_t size, send, prev_send, aligned, sent, fprev;
size_t header_size, file_size;
@@ -78,6 +78,7 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
send = 0;
eagain = 0;
+ flags = 0;
header.elts = headers;
header.size = sizeof(struct iovec);
@@ -261,28 +262,39 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
sent = 0;
+#if (NGX_HAVE_AIO_SENDFILE)
+ flags = c->aio_sendfile ? SF_NODISKIO : 0;
+#endif
+
rc = sendfile(file->file->fd, c->fd, file->file_pos,
- file_size + header_size, &hdtr, &sent, 0);
+ file_size + header_size, &hdtr, &sent, flags);
if (rc == -1) {
err = ngx_errno;
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- if (err == NGX_EINTR) {
- eintr = 1;
+ switch (err) {
+ case NGX_EAGAIN:
+ eagain = 1;
+ break;
- } else {
- eagain = 1;
- }
+ case NGX_EINTR:
+ eintr = 1;
+ break;
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
- "sendfile() sent only %O bytes", sent);
+#if (NGX_HAVE_AIO_SENDFILE)
+ case NGX_EBUSY:
+ c->busy_sendfile = file;
+ break;
+#endif
- } else {
+ default:
wev->error = 1;
(void) ngx_connection_error(c, err, "sendfile() failed");
return NGX_CHAIN_ERROR;
}
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "sendfile() sent only %O bytes", sent);
}
/*
@@ -318,19 +330,22 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
if (rc == -1) {
err = ngx_errno;
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- if (err == NGX_EINTR) {
- eintr = 1;
- }
+ switch (err) {
+ case NGX_EAGAIN:
+ break;
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "writev() not ready");
+ case NGX_EINTR:
+ eintr = 1;
+ break;
- } else {
+ 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");
}
sent = rc > 0 ? rc : 0;
@@ -379,6 +394,12 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
break;
}
+#if (NGX_HAVE_AIO_SENDFILE)
+ if (c->busy_sendfile) {
+ return cl;
+ }
+#endif
+
if (eagain) {
/*
diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c
index e102f27d6..a2225d9c6 100644
--- a/src/os/unix/ngx_linux_sendfile_chain.c
+++ b/src/os/unix/ngx_linux_sendfile_chain.c
@@ -263,19 +263,22 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
if (rc == -1) {
err = ngx_errno;
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- if (err == NGX_EINTR) {
- eintr = 1;
- }
+ switch (err) {
+ case NGX_EAGAIN:
+ break;
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "sendfile() is not ready");
+ case NGX_EINTR:
+ eintr = 1;
+ break;
- } else {
+ default:
wev->error = 1;
ngx_connection_error(c, err, "sendfile() failed");
return NGX_CHAIN_ERROR;
}
+
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "sendfile() is not ready");
}
sent = rc > 0 ? rc : 0;
@@ -290,19 +293,22 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
if (rc == -1) {
err = ngx_errno;
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- if (err == NGX_EINTR) {
- eintr = 1;
- }
+ switch (err) {
+ case NGX_EAGAIN:
+ break;
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "writev() not ready");
+ case NGX_EINTR:
+ eintr = 1;
+ break;
- } else {
+ 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");
}
sent = rc > 0 ? rc : 0;
diff --git a/src/os/unix/ngx_solaris_sendfilev_chain.c b/src/os/unix/ngx_solaris_sendfilev_chain.c
index 2feae2fc8..3a9356cdb 100644
--- a/src/os/unix/ngx_solaris_sendfilev_chain.c
+++ b/src/os/unix/ngx_solaris_sendfilev_chain.c
@@ -168,19 +168,22 @@ ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
if (n == -1) {
err = ngx_errno;
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- if (err == NGX_EINTR) {
- eintr = 1;
- }
+ switch (err) {
+ case NGX_EAGAIN:
+ break;
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
- "sendfilev() sent only %uz bytes", sent);
+ case NGX_EINTR:
+ eintr = 1;
+ break;
- } else {
+ default:
wev->error = 1;
ngx_connection_error(c, err, "sendfilev() failed");
return NGX_CHAIN_ERROR;
}
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "sendfilev() sent only %uz bytes", sent);
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c
index b8754cda3..695cb4978 100644
--- a/src/os/unix/ngx_writev_chain.c
+++ b/src/os/unix/ngx_writev_chain.c
@@ -110,19 +110,22 @@ ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
if (n == -1) {
err = ngx_errno;
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- if (err == NGX_EINTR) {
- eintr = 1;
- }
+ switch (err) {
+ case NGX_EAGAIN:
+ break;
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "writev() not ready");
+ case NGX_EINTR:
+ eintr = 1;
+ break;
- } else {
+ 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");
}
sent = n > 0 ? n : 0;