comparison src/os/unix/ngx_readv_chain.c @ 5852:43512a33e8f2

Merged implementations of ngx_readv_chain(). There's no real need in two separate implementations, with and without kqueue support.
author Valentin Bartenev <vbart@nginx.com>
date Wed, 13 Aug 2014 15:11:45 +0400
parents d1bde5c3c5d2
children b63e829621ab
comparison
equal deleted inserted replaced
5851:150df089fe47 5852:43512a33e8f2
15 #else 15 #else
16 #define NGX_IOVS IOV_MAX 16 #define NGX_IOVS IOV_MAX
17 #endif 17 #endif
18 18
19 19
20 #if (NGX_HAVE_KQUEUE)
21
22 ssize_t 20 ssize_t
23 ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain) 21 ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
24 { 22 {
25 u_char *prev; 23 u_char *prev;
26 ssize_t n, size; 24 ssize_t n, size;
28 ngx_array_t vec; 26 ngx_array_t vec;
29 ngx_event_t *rev; 27 ngx_event_t *rev;
30 struct iovec *iov, iovs[NGX_IOVS]; 28 struct iovec *iov, iovs[NGX_IOVS];
31 29
32 rev = c->read; 30 rev = c->read;
31
32 #if (NGX_HAVE_KQUEUE)
33 33
34 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { 34 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
35 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, 35 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
36 "readv: eof:%d, avail:%d, err:%d", 36 "readv: eof:%d, avail:%d, err:%d",
37 rev->pending_eof, rev->available, rev->kq_errno); 37 rev->pending_eof, rev->available, rev->kq_errno);
55 } else { 55 } else {
56 return NGX_AGAIN; 56 return NGX_AGAIN;
57 } 57 }
58 } 58 }
59 } 59 }
60
61 #endif
60 62
61 prev = NULL; 63 prev = NULL;
62 iov = NULL; 64 iov = NULL;
63 size = 0; 65 size = 0;
64 66
100 102
101 do { 103 do {
102 n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts); 104 n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts);
103 105
104 if (n >= 0) { 106 if (n >= 0) {
107
108 #if (NGX_HAVE_KQUEUE)
109
105 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { 110 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
106 rev->available -= n; 111 rev->available -= n;
107 112
108 /* 113 /*
109 * rev->available may be negative here because some additional 114 * rev->available may be negative here because some additional
139 } 144 }
140 145
141 return n; 146 return n;
142 } 147 }
143 148
149 #endif /* NGX_HAVE_KQUEUE */
150
144 if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) { 151 if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) {
145 rev->ready = 0; 152 rev->ready = 0;
146 } 153 }
147 154
148 if (n == 0) { 155 if (n == 0) {
172 c->read->error = 1; 179 c->read->error = 1;
173 } 180 }
174 181
175 return n; 182 return n;
176 } 183 }
177
178 #else /* ! NGX_HAVE_KQUEUE */
179
180 ssize_t
181 ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
182 {
183 u_char *prev;
184 ssize_t n, size;
185 ngx_err_t err;
186 ngx_array_t vec;
187 ngx_event_t *rev;
188 struct iovec *iov, iovs[NGX_IOVS];
189
190 prev = NULL;
191 iov = NULL;
192 size = 0;
193
194 vec.elts = iovs;
195 vec.nelts = 0;
196 vec.size = sizeof(struct iovec);
197 vec.nalloc = NGX_IOVS;
198 vec.pool = c->pool;
199
200 /* coalesce the neighbouring bufs */
201
202 while (chain) {
203 if (prev == chain->buf->last) {
204 iov->iov_len += chain->buf->end - chain->buf->last;
205
206 } else {
207 if (vec.nelts >= IOV_MAX) {
208 break;
209 }
210
211 iov = ngx_array_push(&vec);
212 if (iov == NULL) {
213 return NGX_ERROR;
214 }
215
216 iov->iov_base = (void *) chain->buf->last;
217 iov->iov_len = chain->buf->end - chain->buf->last;
218 }
219
220 size += chain->buf->end - chain->buf->last;
221 prev = chain->buf->end;
222 chain = chain->next;
223 }
224
225 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
226 "readv: %d:%d", vec.nelts, iov->iov_len);
227
228 rev = c->read;
229
230 do {
231 n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts);
232
233 if (n == 0) {
234 rev->ready = 0;
235 rev->eof = 1;
236
237 return n;
238
239 } else if (n > 0) {
240
241 if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) {
242 rev->ready = 0;
243 }
244
245 return n;
246 }
247
248 err = ngx_socket_errno;
249
250 if (err == NGX_EAGAIN || err == NGX_EINTR) {
251 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
252 "readv() not ready");
253 n = NGX_AGAIN;
254
255 } else {
256 n = ngx_connection_error(c, err, "readv() failed");
257 break;
258 }
259
260 } while (err == NGX_EINTR);
261
262 rev->ready = 0;
263
264 if (n == NGX_ERROR) {
265 c->read->error = 1;
266 }
267
268 return n;
269 }
270
271 #endif /* NGX_HAVE_KQUEUE */