3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
10 #include <ngx_event.h>
19 ngx_readv_chain(ngx_connection_t
*c
, ngx_chain_t
*chain
)
26 struct iovec
*iov
, iovs
[NGX_IOVS
];
30 if (ngx_event_flags
& NGX_USE_KQUEUE_EVENT
) {
31 ngx_log_debug3(NGX_LOG_DEBUG_EVENT
, c
->log
, 0,
32 "readv: eof:%d, avail:%d, err:%d",
33 rev
->pending_eof
, rev
->available
, rev
->kq_errno
);
35 if (rev
->available
== 0) {
36 if (rev
->pending_eof
) {
40 ngx_log_error(NGX_LOG_INFO
, c
->log
, rev
->kq_errno
,
41 "kevent() reported about an closed connection");
45 ngx_set_socket_errno(rev
->kq_errno
);
63 vec
.size
= sizeof(struct iovec
);
64 vec
.nalloc
= NGX_IOVS
;
67 /* coalesce the neighbouring bufs */
70 if (prev
== chain
->buf
->last
) {
71 iov
->iov_len
+= chain
->buf
->end
- chain
->buf
->last
;
74 if (vec
.nelts
>= IOV_MAX
) {
78 iov
= ngx_array_push(&vec
);
83 iov
->iov_base
= (void *) chain
->buf
->last
;
84 iov
->iov_len
= chain
->buf
->end
- chain
->buf
->last
;
87 size
+= chain
->buf
->end
- chain
->buf
->last
;
88 prev
= chain
->buf
->end
;
92 ngx_log_debug2(NGX_LOG_DEBUG_EVENT
, c
->log
, 0,
93 "readv: %d, last:%d", vec
.nelts
, iov
->iov_len
);
98 n
= readv(c
->fd
, (struct iovec
*) vec
.elts
, vec
.nelts
);
101 if (ngx_event_flags
& NGX_USE_KQUEUE_EVENT
) {
105 * rev->available may be negative here because some additional
106 * bytes may be received between kevent() and recv()
109 if (rev
->available
<= 0) {
110 if (!rev
->pending_eof
) {
114 if (rev
->available
< 0) {
122 * on FreeBSD recv() may return 0 on closed socket
123 * even if kqueue reported about available data
127 ngx_log_error(NGX_LOG_ALERT
, c
->log
, 0,
128 "readv() returned 0 while kevent() reported "
129 "%d available bytes", rev
->available
);
150 err
= ngx_socket_errno
;
152 if (err
== NGX_EAGAIN
|| err
== NGX_EINTR
) {
153 ngx_log_debug0(NGX_LOG_DEBUG_EVENT
, c
->log
, err
,
154 "readv() not ready");
158 n
= ngx_connection_error(c
, err
, "readv() failed");
162 } while (err
== NGX_EINTR
);
166 if (n
== NGX_ERROR
) {
173 #else /* ! NGX_HAVE_KQUEUE */
176 ngx_readv_chain(ngx_connection_t
*c
, ngx_chain_t
*chain
)
183 struct iovec
*iov
, iovs
[NGX_IOVS
];
191 vec
.size
= sizeof(struct iovec
);
192 vec
.nalloc
= NGX_IOVS
;
195 /* coalesce the neighbouring bufs */
198 if (prev
== chain
->buf
->last
) {
199 iov
->iov_len
+= chain
->buf
->end
- chain
->buf
->last
;
202 if (vec
.nelts
>= IOV_MAX
) {
206 iov
= ngx_array_push(&vec
);
211 iov
->iov_base
= (void *) chain
->buf
->last
;
212 iov
->iov_len
= chain
->buf
->end
- chain
->buf
->last
;
215 size
+= chain
->buf
->end
- chain
->buf
->last
;
216 prev
= chain
->buf
->end
;
220 ngx_log_debug2(NGX_LOG_DEBUG_EVENT
, c
->log
, 0,
221 "readv: %d:%d", vec
.nelts
, iov
->iov_len
);
226 n
= readv(c
->fd
, (struct iovec
*) vec
.elts
, vec
.nelts
);
236 if (n
< size
&& !(ngx_event_flags
& NGX_USE_GREEDY_EVENT
)) {
243 err
= ngx_socket_errno
;
245 if (err
== NGX_EAGAIN
|| err
== NGX_EINTR
) {
246 ngx_log_debug0(NGX_LOG_DEBUG_EVENT
, c
->log
, err
,
247 "readv() not ready");
251 n
= ngx_connection_error(c
, err
, "readv() failed");
255 } while (err
== NGX_EINTR
);
259 if (n
== NGX_ERROR
) {
266 #endif /* NGX_HAVE_KQUEUE */