Mercurial > hg > nginx
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 */ |