3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
18 ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
25 struct iovec *iov, iovs[NGX_IOVS];
29 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
30 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
31 "readv: eof:%d, avail:%d, err:%d",
32 rev->pending_eof, rev->available, rev->kq_errno);
34 if (rev->available == 0) {
35 if (rev->pending_eof) {
39 ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
40 "kevent() reported about an closed connection");
44 ngx_set_socket_errno(rev->kq_errno);
62 vec.size = sizeof(struct iovec);
63 vec.nalloc = NGX_IOVS;
66 /* coalesce the neighbouring bufs */
69 if (prev == chain->buf->last) {
70 iov->iov_len += chain->buf->end - chain->buf->last;
73 iov = ngx_array_push(&vec);
78 iov->iov_base = (void *) chain->buf->last;
79 iov->iov_len = chain->buf->end - chain->buf->last;
82 size += chain->buf->end - chain->buf->last;
83 prev = chain->buf->end;
87 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
88 "readv: %d, last:%d", vec.nelts, iov->iov_len);
93 n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts);
96 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
100 * rev->available may be negative here because some additional
101 * bytes may be received between kevent() and recv()
104 if (rev->available <= 0) {
105 if (!rev->pending_eof) {
109 if (rev->available < 0) {
117 * on FreeBSD recv() may return 0 on closed socket
118 * even if kqueue reported about available data
122 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
123 "readv() returned 0 while kevent() reported "
124 "%d available bytes", rev->available);
145 err = ngx_socket_errno;
147 if (err == NGX_EAGAIN || err == NGX_EINTR) {
148 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
149 "readv() not ready");
153 n = ngx_connection_error(c, err, "readv() failed");
157 } while (err == NGX_EINTR);
168 #else /* ! NGX_HAVE_KQUEUE */
171 ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
178 struct iovec *iov, iovs[NGX_IOVS];
186 vec.size = sizeof(struct iovec);
187 vec.nalloc = NGX_IOVS;
190 /* coalesce the neighbouring bufs */
193 if (prev == chain->buf->last) {
194 iov->iov_len += chain->buf->end - chain->buf->last;
197 iov = ngx_array_push(&vec);
202 iov->iov_base = (void *) chain->buf->last;
203 iov->iov_len = chain->buf->end - chain->buf->last;
206 size += chain->buf->end - chain->buf->last;
207 prev = chain->buf->end;
211 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
212 "readv: %d:%d", vec.nelts, iov->iov_len);
217 n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts);
227 if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) {
234 err = ngx_socket_errno;
236 if (err == NGX_EAGAIN || err == NGX_EINTR) {
237 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
238 "readv() not ready");
242 n = ngx_connection_error(c, err, "readv() failed");
246 } while (err == NGX_EINTR);
257 #endif /* NGX_HAVE_KQUEUE */