aboutsummaryrefslogtreecommitdiff
path: root/src/os
diff options
context:
space:
mode:
Diffstat (limited to 'src/os')
-rw-r--r--src/os/unix/ngx_files.c44
-rw-r--r--src/os/unix/ngx_files.h4
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c27
-rw-r--r--src/os/unix/ngx_writev_chain.c50
4 files changed, 81 insertions, 44 deletions
diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c
index adafc17cf..f07ef5444 100644
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -50,9 +50,10 @@ ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
}
-ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
+ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl,
off_t offset, ngx_pool_t *pool)
{
+ char *prev;
size_t size;
ssize_t n;
struct iovec *iov;
@@ -61,20 +62,39 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
/* use pwrite() if there's the only hunk in a chain */
- if (ce->next == NULL) {
- return ngx_write_file(file, ce->hunk->pos,
- ce->hunk->last - ce->hunk->pos, offset);
+ if (cl->next == NULL) {
+ return ngx_write_file(file, cl->hunk->pos,
+ cl->hunk->last - cl->hunk->pos, offset);
}
- ngx_init_array(io, pool, 10, sizeof(struct iovec), NGX_ERROR);
+ prev = NULL;
+ iov = NULL;
size = 0;
- while (ce) {
- ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR);
- iov->iov_base = ce->hunk->pos;
- iov->iov_len = ce->hunk->last - ce->hunk->pos;
- size += ce->hunk->last - ce->hunk->pos;
- ce = ce->next;
+ ngx_init_array(io, pool, 10, sizeof(struct iovec), NGX_ERROR);
+
+ /* create the iovec and coalesce the neighbouring hunks */
+
+ while (cl) {
+ if (prev == cl->hunk->pos) {
+ iov->iov_len += cl->hunk->last - cl->hunk->pos;
+
+ } else {
+ ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR);
+ iov->iov_base = cl->hunk->pos;
+ iov->iov_len = cl->hunk->last - cl->hunk->pos;
+ }
+
+ size += cl->hunk->last - cl->hunk->pos;
+ prev = cl->hunk->last;
+ cl = cl->next;
+ }
+
+ /* use pwrite() if there's the only iovec buffer */
+
+ if (io.nelts == 1) {
+ iov = io.elts;
+ return ngx_write_file(file, iov[0].iov_base, iov[0].iov_len, offset);
}
if (file->offset != offset) {
@@ -84,7 +104,7 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
}
}
- n = writev(file->fd, (struct iovec *) io.elts, io.nelts);
+ n = writev(file->fd, io.elts, io.nelts);
if (n == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "writev() failed");
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index e2af7222c..494ec55b1 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -45,6 +45,10 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
off_t offset, ngx_pool_t *pool);
+#define ngx_rename_file rename
+#define ngx_rename_file_n "rename"
+
+
#define ngx_mkdir(name) mkdir(name, 0700)
#define ngx_mkdir_n "mkdir()"
diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
index c24149928..65dfc03f6 100644
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -31,13 +31,28 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
struct sf_hdtr hdtr;
ngx_err_t err;
ngx_array_t header, trailer;
+ ngx_event_t *wev;
ngx_hunk_t *file;
ngx_chain_t *cl, *tail;
- if (!c->write->ready) {
+ wev = c->write;
+
+ if (!wev->ready) {
return in;
}
+#if (HAVE_KQUEUE)
+
+ if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) && wev->kq_eof) {
+ ngx_log_error(NGX_LOG_ERR, c->log, wev->kq_errno,
+ "kevent() reported about closed connection");
+
+ wev->error = 1;
+ return NGX_CHAIN_ERROR;
+ }
+
+#endif
+
do {
cl = in;
file = NULL;
@@ -181,7 +196,7 @@ ngx_log_debug(c->log, "NOPUSH");
"sendfile() sent only %qd bytes", sent);
} else {
- c->write->error = 1;
+ wev->error = 1;
ngx_log_error(NGX_LOG_CRIT, c->log, err,
"sendfile() failed");
return NGX_CHAIN_ERROR;
@@ -194,7 +209,7 @@ ngx_log_debug(c->log, "NOPUSH");
#endif
} else {
- rc = writev(c->fd, (struct iovec *) header.elts, header.nelts);
+ rc = writev(c->fd, header.elts, header.nelts);
if (rc == -1) {
err = ngx_errno;
@@ -206,7 +221,7 @@ ngx_log_debug(c->log, "NOPUSH");
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
} else {
- c->write->error = 1;
+ wev->error = 1;
ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
return NGX_CHAIN_ERROR;
}
@@ -268,7 +283,7 @@ ngx_log_debug(c->log, "NOPUSH");
* return EAGAIN right away and would not send anything
*/
- c->write->ready = 0;
+ wev->ready = 0;
break;
}
@@ -277,7 +292,7 @@ ngx_log_debug(c->log, "NOPUSH");
} while ((tail && tail == in) || eintr);
if (in) {
- c->write->ready = 0;
+ wev->ready = 0;
}
return in;
diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c
index 70141e341..6ead65f3a 100644
--- a/src/os/unix/ngx_writev_chain.c
+++ b/src/os/unix/ngx_writev_chain.c
@@ -11,34 +11,34 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
off_t sent;
struct iovec *iov;
ngx_err_t err;
- ngx_array_t iovecs;
- ngx_chain_t *ce;
+ ngx_array_t io;
+ ngx_chain_t *cl;
if (!c->write->ready) {
return in;
}
- ngx_init_array(iovecs, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
+ ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
prev = NULL;
iov = NULL;
- /* create the iovec and coalesce the neighbouring chain entries */
- for (ce = in; ce; ce = ce->next) {
+ /* create the iovec and coalesce the neighbouring hunks */
+ for (cl = in; cl; cl = cl->next) {
- if (prev == ce->hunk->pos) {
- iov->iov_len += ce->hunk->last - ce->hunk->pos;
- prev = ce->hunk->last;
+ if (prev == cl->hunk->pos) {
+ iov->iov_len += cl->hunk->last - cl->hunk->pos;
+ prev = cl->hunk->last;
} else {
- ngx_test_null(iov, ngx_push_array(&iovecs), NGX_CHAIN_ERROR);
- iov->iov_base = ce->hunk->pos;
- iov->iov_len = ce->hunk->last - ce->hunk->pos;
- prev = ce->hunk->last;
+ ngx_test_null(iov, ngx_push_array(&io), NGX_CHAIN_ERROR);
+ iov->iov_base = cl->hunk->pos;
+ iov->iov_len = cl->hunk->last - cl->hunk->pos;
+ prev = cl->hunk->last;
}
}
- n = writev(c->fd, iovecs.elts, iovecs.nelts);
+ n = writev(c->fd, io.elts, io.nelts);
if (n == -1) {
err = ngx_errno;
@@ -62,42 +62,40 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
c->sent += sent;
- for (ce = in; ce && sent > 0; ce = ce->next) {
+ for (cl = in; cl && sent > 0; cl = cl->next) {
- size = ce->hunk->last - ce->hunk->pos;
+ size = cl->hunk->last - cl->hunk->pos;
ngx_log_debug(c->log, "SIZE: %d" _ size);
if (sent >= size) {
sent -= size;
- if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
- ce->hunk->pos = ce->hunk->last;
+ if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
+ cl->hunk->pos = cl->hunk->last;
}
#if 0
- if (ce->hunk->type & NGX_HUNK_FILE) {
- ce->hunk->file_pos = ce->hunk->file_last;
+ if (cl->hunk->type & NGX_HUNK_FILE) {
+ cl->hunk->file_pos = cl->hunk->file_last;
}
#endif
continue;
}
- if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
- ce->hunk->pos += sent;
+ if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
+ cl->hunk->pos += sent;
}
#if 0
- if (ce->hunk->type & NGX_HUNK_FILE) {
- ce->hunk->file_pos += sent;
+ if (cl->hunk->type & NGX_HUNK_FILE) {
+ cl->hunk->file_pos += sent;
}
#endif
break;
}
- ngx_destroy_array(&iovecs);
-
- return ce;
+ return cl;
}