One Level Up
  Top Level
 
  src/os/unix/ngx_solaris_sendfilev_chain.c - nginx-1.7.10
 Data types defined
 
 Functions defined
 
 Macros defined
 
 Source code
  
 
 
 
- #include <ngx_config.h>
 
- #include <ngx_core.h>
 
- #include <ngx_event.h>
 
 
 
- #if (NGX_TEST_BUILD_SOLARIS_SENDFILEV)
 
 
 
- typedef struct sendfilevec {
 
-     int     sfv_fd;
 
-     u_int   sfv_flag;
 
-     off_t   sfv_off;
 
-     size_t  sfv_len;
 
- } sendfilevec_t;
 
 
- #define SFV_FD_SELF  -2
 
 
- static ssize_t sendfilev(int fd, const struct sendfilevec *vec,
 
-     int sfvcnt, size_t *xferred)
 
- {
 
-     return -1;
 
- }
 
 
- ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
 
-     off_t limit);
 
 
- #endif
 
 
 
- #define NGX_SENDFILEVECS  NGX_IOVS_PREALLOCATE
 
 
 
- 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           size, send, prev_send, aligned, fprev;
 
-     size_t          sent;
 
-     ssize_t         n;
 
-     ngx_int_t       eintr;
 
-     ngx_err_t       err;
 
-     ngx_uint_t      nsfv;
 
-     sendfilevec_t  *sfv, sfvs[NGX_SENDFILEVECS];
 
-     ngx_event_t    *wev;
 
-     ngx_chain_t    *cl;
 
 
-     wev = c->write;
 
 
-     if (!wev->ready) {
 
-         return in;
 
-     }
 
 
-     if (!c->sendfile) {
 
-         return ngx_writev_chain(c, in, limit);
 
-     }
 
 
 
-     
 
-     if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) {
 
-         limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
 
-     }
 
 
 
-     send = 0;
 
 
-     for ( ;; ) {
 
-         fd = SFV_FD_SELF;
 
-         prev = NULL;
 
-         fprev = 0;
 
-         sfv = NULL;
 
-         eintr = 0;
 
-         sent = 0;
 
-         prev_send = send;
 
 
-         nsfv = 0;
 
 
-         
 
-         for (cl = in; cl && send < limit; cl = cl->next) {
 
 
-             if (ngx_buf_special(cl->buf)) {
 
-                 continue;
 
-             }
 
 
-             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 += (size_t) size;
 
 
-                 } else {
 
-                     if (nsfv == NGX_SENDFILEVECS) {
 
-                         break;
 
-                     }
 
 
-                     sfv = &sfvs[nsfv++];
 
 
-                     sfv->sfv_fd = SFV_FD_SELF;
 
-                     sfv->sfv_flag = 0;
 
-                     sfv->sfv_off = (off_t) (uintptr_t) cl->buf->pos;
 
-                     sfv->sfv_len = (size_t) size;
 
-                 }
 
 
-                 prev = cl->buf->pos + (size_t) size;
 
-                 send += size;
 
 
-             } else {
 
-                 prev = NULL;
 
 
-                 size = cl->buf->file_last - cl->buf->file_pos;
 
 
-                 if (send + size > limit) {
 
-                     size = limit - send;
 
 
-                     aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
 
-                                & ~((off_t) 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 += (size_t) size;
 
 
-                 } else {
 
-                     if (nsfv == NGX_SENDFILEVECS) {
 
-                         break;
 
-                     }
 
 
-                     sfv = &sfvs[nsfv++];
 
 
-                     fd = cl->buf->file->fd;
 
-                     sfv->sfv_fd = fd;
 
-                     sfv->sfv_flag = 0;
 
-                     sfv->sfv_off = cl->buf->file_pos;
 
-                     sfv->sfv_len = (size_t) size;
 
-                 }
 
 
-                 fprev = cl->buf->file_pos + size;
 
-                 send += size;
 
-             }
 
-         }
 
 
-         n = sendfilev(c->fd, sfvs, nsfv, &sent);
 
 
-         if (n == -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, "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,
 
-                        "sendfilev: %z %z", n, sent);
 
 
-         c->sent += sent;
 
 
-         in = ngx_chain_update_sent(in, sent);
 
 
-         if (eintr) {
 
-             send = prev_send + sent;
 
-             continue;
 
-         }
 
 
-         if (send - prev_send != (off_t) sent) {
 
-             wev->ready = 0;
 
-             return in;
 
-         }
 
 
-         if (send >= limit || in == NULL) {
 
-             return in;
 
-         }
 
-     }
 
- }
 
  One Level Up
  Top Level