aboutsummaryrefslogtreecommitdiff
path: root/src/os/unix/ngx_solaris_sendfilev_chain.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2004-06-21 15:59:32 +0000
committerIgor Sysoev <igor@sysoev.ru>2004-06-21 15:59:32 +0000
commitef06648615d6ce6e000e6c737f80c2ba9fa04d3a (patch)
tree5f840689ca43ecba7218f9709f1bdfaa27611f53 /src/os/unix/ngx_solaris_sendfilev_chain.c
parent73a73b5a60b1c6c985f3e9a5d7cddbe292ad01a4 (diff)
downloadnginx-ef06648615d6ce6e000e6c737f80c2ba9fa04d3a.tar.gz
nginx-ef06648615d6ce6e000e6c737f80c2ba9fa04d3a.zip
nginx-0.0.7-2004-06-21-19:59:32 import
Diffstat (limited to 'src/os/unix/ngx_solaris_sendfilev_chain.c')
-rw-r--r--src/os/unix/ngx_solaris_sendfilev_chain.c80
1 files changed, 54 insertions, 26 deletions
diff --git a/src/os/unix/ngx_solaris_sendfilev_chain.c b/src/os/unix/ngx_solaris_sendfilev_chain.c
index 352c1623d..07a8a8d4e 100644
--- a/src/os/unix/ngx_solaris_sendfilev_chain.c
+++ b/src/os/unix/ngx_solaris_sendfilev_chain.c
@@ -9,14 +9,15 @@
#include <ngx_event.h>
-ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
+ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
+ off_t limit)
{
int fd;
u_char *prev;
- off_t fprev;
- size_t sent, size;
+ off_t fprev, sprev, send, aligned;
+ size_t size, sent;
ssize_t n;
- ngx_int_t eintr;
+ ngx_int_t eintr, complete;
ngx_err_t err;
sendfilevec_t *sfv;
ngx_array_t vec;
@@ -29,20 +30,25 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
return in;
}
- do {
+ send = 0;
+ complete = 0;
+
+ for ( ;; ) {
fd = SFV_FD_SELF;
prev = NULL;
fprev = 0;
sfv = NULL;
eintr = 0;
sent = 0;
+ sprev = send;
ngx_init_array(vec, c->pool, 10, sizeof(sendfilevec_t),
NGX_CHAIN_ERROR);
/* create the sendfilevec and coalesce the neighbouring bufs */
- for (cl = in; cl && vec.nelts < IOV_MAX; cl = cl->next) {
+ for (cl = in; cl && vec.nelts < IOV_MAX && send < limit; cl = cl->next)
+ {
if (ngx_buf_special(cl->buf)) {
continue;
}
@@ -50,24 +56,44 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
if (ngx_buf_in_memory_only(cl->buf)) {
fd = SFV_FD_SELF;
+ size = cl->buf->last - cl->buf->pos;
+
+ if (send + size > limit) {
+ size = limit - send;
+ }
+
if (prev == cl->buf->pos) {
- sfv->sfv_len += cl->buf->last - cl->buf->pos;
+ sfv->sfv_len += size;
} else {
ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR);
sfv->sfv_fd = SFV_FD_SELF;
sfv->sfv_flag = 0;
sfv->sfv_off = (off_t) (uintptr_t) cl->buf->pos;
- sfv->sfv_len = cl->buf->last - cl->buf->pos;
+ sfv->sfv_len = size;
}
- prev = cl->buf->last;
+ prev = cl->buf->pos + size;
+ send += size;
} else {
prev = NULL;
+ size = (size_t) (cl->buf->file_last - cl->buf->file_pos);
+
+ 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;
+ }
+ }
+
if (fd == cl->buf->file->fd && fprev == cl->buf->file_pos) {
- sfv->sfv_len += cl->buf->file_last - cl->buf->file_pos;
+ sfv->sfv_len += size;
} else {
ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR);
@@ -75,20 +101,14 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
sfv->sfv_fd = fd;
sfv->sfv_flag = 0;
sfv->sfv_off = cl->buf->file_pos;
- sfv->sfv_len = cl->buf->file_last - cl->buf->file_pos;
+ sfv->sfv_len = size;
}
- fprev = cl->buf->file_last;
+ fprev = cl->buf->file_pos + size;
+ send += size;
}
}
- /*
- * the tail is the rest of the chain that exceedes a single
- * sendfilev() capability, IOV_MAX in Solaris is limited by 16
- */
-
- tail = cl;
-
n = sendfilev(c->fd, vec.elts, vec.nelts, &sent);
if (n == -1) {
@@ -113,6 +133,10 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"sendfilev: %d " SIZE_T_FMT, n, sent);
+ if (send - sprev == sent) {
+ complete = 1;
+ }
+
c->sent += sent;
for (cl = in; cl; cl = cl->next) {
@@ -152,15 +176,19 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
break;
}
- in = cl;
+ if (eintr) {
+ continue;
+ }
- /* "tail == in" means that a single sendfilev() is complete */
+ if (!complete) {
+ wev->ready = 0;
+ return cl;
+ }
- } while ((tail && tail == in) || eintr);
+ if (send >= limit || cl == NULL) {
+ return cl;
+ }
- if (in) {
- wev->ready = 0;
+ in = cl;
}
-
- return in;
}