One Level Up
  Top Level
 
  src/os/unix/ngx_readv_chain.c - nginx-1.7.10
 Functions defined
 
 Source code
  
 
 
 
- #include <ngx_config.h>
 
- #include <ngx_core.h>
 
- #include <ngx_event.h>
 
 
 
- ssize_t
 
- ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain, off_t limit)
 
- {
 
-     u_char        *prev;
 
-     ssize_t        n, size;
 
-     ngx_err_t      err;
 
-     ngx_array_t    vec;
 
-     ngx_event_t   *rev;
 
-     struct iovec  *iov, iovs[NGX_IOVS_PREALLOCATE];
 
 
-     rev = c->read;
 
 
- #if (NGX_HAVE_KQUEUE)
 
 
-     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
 
-         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
 
-                        "readv: eof:%d, avail:%d, err:%d",
 
-                        rev->pending_eof, rev->available, rev->kq_errno);
 
 
-         if (rev->available == 0) {
 
-             if (rev->pending_eof) {
 
-                 rev->ready = 0;
 
-                 rev->eof = 1;
 
 
-                 ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
 
-                               "kevent() reported about an closed connection");
 
 
-                 if (rev->kq_errno) {
 
-                     rev->error = 1;
 
-                     ngx_set_socket_errno(rev->kq_errno);
 
-                     return NGX_ERROR;
 
-                 }
 
 
-                 return 0;
 
 
-             } else {
 
-                 return NGX_AGAIN;
 
-             }
 
-         }
 
-     }
 
 
- #endif
 
 
-     prev = NULL;
 
-     iov = NULL;
 
-     size = 0;
 
 
-     vec.elts = iovs;
 
-     vec.nelts = 0;
 
-     vec.size = sizeof(struct iovec);
 
-     vec.nalloc = NGX_IOVS_PREALLOCATE;
 
-     vec.pool = c->pool;
 
 
-     
 
-     while (chain) {
 
-         n = chain->buf->end - chain->buf->last;
 
 
-         if (limit) {
 
-             if (size >= limit) {
 
-                 break;
 
-             }
 
 
-             if (size + n > limit) {
 
-                 n = (ssize_t) (limit - size);
 
-             }
 
-         }
 
 
-         if (prev == chain->buf->last) {
 
-             iov->iov_len += n;
 
 
-         } else {
 
-             if (vec.nelts >= IOV_MAX) {
 
-                 break;
 
-             }
 
 
-             iov = ngx_array_push(&vec);
 
-             if (iov == NULL) {
 
-                 return NGX_ERROR;
 
-             }
 
 
-             iov->iov_base = (void *) chain->buf->last;
 
-             iov->iov_len = n;
 
-         }
 
 
-         size += n;
 
-         prev = chain->buf->end;
 
-         chain = chain->next;
 
-     }
 
 
-     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
 
-                    "readv: %d, last:%d", vec.nelts, iov->iov_len);
 
 
-     do {
 
-         n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts);
 
 
-         if (n >= 0) {
 
 
- #if (NGX_HAVE_KQUEUE)
 
 
-             if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
 
-                 rev->available -= n;
 
 
-                 
 
-                 if (rev->available <= 0) {
 
-                     if (!rev->pending_eof) {
 
-                         rev->ready = 0;
 
-                     }
 
 
-                     if (rev->available < 0) {
 
-                         rev->available = 0;
 
-                     }
 
-                 }
 
 
-                 if (n == 0) {
 
 
-                     
 
- #if 0
 
- #endif
 
 
-                     rev->ready = 0;
 
-                     rev->eof = 1;
 
-                     rev->available = 0;
 
-                 }
 
 
-                 return n;
 
-             }
 
 
- #endif 
 
-             if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) {
 
-                 rev->ready = 0;
 
-             }
 
 
-             if (n == 0) {
 
-                 rev->eof = 1;
 
-             }
 
 
-             return n;
 
-         }
 
 
-         err = ngx_socket_errno;
 
 
-         if (err == NGX_EAGAIN || err == NGX_EINTR) {
 
-             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
 
-                            "readv() not ready");
 
-             n = NGX_AGAIN;
 
 
-         } else {
 
-             n = ngx_connection_error(c, err, "readv() failed");
 
-             break;
 
-         }
 
 
-     } while (err == NGX_EINTR);
 
 
-     rev->ready = 0;
 
 
-     if (n == NGX_ERROR) {
 
-         c->read->error = 1;
 
-     }
 
 
-     return n;
 
- }
 
  One Level Up
  Top Level