Mercurial > hg > nginx
diff src/os/unix/ngx_solaris_sendfilev_chain.c @ 362:7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 21 Jun 2004 15:59:32 +0000 |
parents | e366ba5db8f8 |
children | 5e73d0ea4dab |
line wrap: on
line diff
--- 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 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 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 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_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 break; } - in = cl; - - /* "tail == in" means that a single sendfilev() is complete */ - - } while ((tail && tail == in) || eintr); + if (eintr) { + continue; + } - if (in) { - wev->ready = 0; + if (!complete) { + wev->ready = 0; + return cl; + } + + if (send >= limit || cl == NULL) { + return cl; + } + + in = cl; } - - return in; }