annotate src/os/unix/ngx_readv_chain.c @ 391:1d9bef53cd8e

Range filter: late_ranges functionality. Add one more filtering point after postpone filter. This allows to serve range capable replies with subrequests. It's not as efficient as range filtering for static data (i.e. doesn't save us from reading data from disk if some filter needs them in memory), but it may save some network bandwidth for us and for our users.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 21 Jul 2008 05:33:01 +0400
parents fae16d0c5bf4
children c456a023113c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
1
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
2 /*
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
4 */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
5
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
6
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
7 #include <ngx_config.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
8 #include <ngx_core.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
9 #include <ngx_event.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
10
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
11
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
12 #define NGX_IOVS 16
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
13
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
14
18
6f8b0dc0f8dd nginx 0.1.9
Igor Sysoev <http://sysoev.ru>
parents: 4
diff changeset
15 #if (NGX_HAVE_KQUEUE)
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
16
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
17 ssize_t
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
18 ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
19 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
20 u_char *prev;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
21 ssize_t n, size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
22 ngx_err_t err;
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
23 ngx_array_t vec;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
24 ngx_event_t *rev;
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
25 struct iovec *iov, iovs[NGX_IOVS];
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
26
126
df17fbafec8f nginx 0.3.10
Igor Sysoev <http://sysoev.ru>
parents: 110
diff changeset
27 rev = c->read;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
28
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
29 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
30 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
31 "readv: eof:%d, avail:%d, err:%d",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
32 rev->pending_eof, rev->available, rev->kq_errno);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
33
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
34 if (rev->available == 0) {
136
3656228c0b56 nginx 0.3.15
Igor Sysoev <http://sysoev.ru>
parents: 130
diff changeset
35 if (rev->pending_eof) {
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
36 rev->ready = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
37 rev->eof = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
38
136
3656228c0b56 nginx 0.3.15
Igor Sysoev <http://sysoev.ru>
parents: 130
diff changeset
39 ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
3656228c0b56 nginx 0.3.15
Igor Sysoev <http://sysoev.ru>
parents: 130
diff changeset
40 "kevent() reported about an closed connection");
3656228c0b56 nginx 0.3.15
Igor Sysoev <http://sysoev.ru>
parents: 130
diff changeset
41
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
42 if (rev->kq_errno) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
43 rev->error = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
44 ngx_set_socket_errno(rev->kq_errno);
136
3656228c0b56 nginx 0.3.15
Igor Sysoev <http://sysoev.ru>
parents: 130
diff changeset
45 return NGX_ERROR;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
46 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
47
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
48 return 0;
136
3656228c0b56 nginx 0.3.15
Igor Sysoev <http://sysoev.ru>
parents: 130
diff changeset
49
3656228c0b56 nginx 0.3.15
Igor Sysoev <http://sysoev.ru>
parents: 130
diff changeset
50 } else {
3656228c0b56 nginx 0.3.15
Igor Sysoev <http://sysoev.ru>
parents: 130
diff changeset
51 return NGX_AGAIN;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
52 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
53 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
54 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
55
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
56 prev = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
57 iov = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
58 size = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
59
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
60 vec.elts = iovs;
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
61 vec.nelts = 0;
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
62 vec.size = sizeof(struct iovec);
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
63 vec.nalloc = NGX_IOVS;
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
64 vec.pool = c->pool;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
65
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
66 /* coalesce the neighbouring bufs */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
67
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
68 while (chain) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
69 if (prev == chain->buf->last) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
70 iov->iov_len += chain->buf->end - chain->buf->last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
71
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
72 } else {
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
73 iov = ngx_array_push(&vec);
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
74 if (iov == NULL) {
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
75 return NGX_ERROR;
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
76 }
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
77
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
78 iov->iov_base = (void *) chain->buf->last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
79 iov->iov_len = chain->buf->end - chain->buf->last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
80 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
81
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
82 size += chain->buf->end - chain->buf->last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
83 prev = chain->buf->end;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
84 chain = chain->next;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
85 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
86
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
87 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
88 "readv: %d, last:%d", vec.nelts, iov->iov_len);
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
89
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
90 rev = c->read;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
91
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
92 do {
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
93 n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts);
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
94
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
95 if (n >= 0) {
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
96 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
97 rev->available -= n;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
98
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
99 /*
136
3656228c0b56 nginx 0.3.15
Igor Sysoev <http://sysoev.ru>
parents: 130
diff changeset
100 * rev->available may be negative here because some additional
3656228c0b56 nginx 0.3.15
Igor Sysoev <http://sysoev.ru>
parents: 130
diff changeset
101 * bytes may be received between kevent() and recv()
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
102 */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
103
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
104 if (rev->available <= 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
105 if (!rev->pending_eof) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
106 rev->ready = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
107 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
108
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
109 if (rev->available < 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
110 rev->available = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
111 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
112 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
113
154
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
114 if (n == 0) {
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
115
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
116 /*
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
117 * on FreeBSD recv() may return 0 on closed socket
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
118 * even if kqueue reported about available data
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
119 */
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
120
176
fae16d0c5bf4 nginx 0.3.35
Igor Sysoev <http://sysoev.ru>
parents: 158
diff changeset
121 #if 0
154
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
122 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
158
2d15b82126ed nginx 0.3.26
Igor Sysoev <http://sysoev.ru>
parents: 154
diff changeset
123 "readv() returned 0 while kevent() reported "
154
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
124 "%d available bytes", rev->available);
176
fae16d0c5bf4 nginx 0.3.35
Igor Sysoev <http://sysoev.ru>
parents: 158
diff changeset
125 #endif
154
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
126
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
127 rev->eof = 1;
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
128 rev->available = 0;
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
129 }
bb61aa162c6b nginx 0.3.24
Igor Sysoev <http://sysoev.ru>
parents: 136
diff changeset
130
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
131 return n;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
132 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
133
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
134 if (n < size) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
135 rev->ready = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
136 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
137
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
138 if (n == 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
139 rev->eof = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
140 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
141
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
142 return n;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
143 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
144
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
145 err = ngx_socket_errno;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
146
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
147 if (err == NGX_EAGAIN || err == NGX_EINTR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
148 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
149 "readv() not ready");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
150 n = NGX_AGAIN;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
151
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
152 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
153 n = ngx_connection_error(c, err, "readv() failed");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
154 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
155 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
156
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
157 } while (err == NGX_EINTR);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
158
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
159 rev->ready = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
160
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
161 if (n == NGX_ERROR){
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
162 c->read->error = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
163 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
164
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
165 return n;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
166 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
167
18
6f8b0dc0f8dd nginx 0.1.9
Igor Sysoev <http://sysoev.ru>
parents: 4
diff changeset
168 #else /* ! NGX_HAVE_KQUEUE */
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
169
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
170 ssize_t
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
171 ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
172 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
173 u_char *prev;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
174 ssize_t n, size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
175 ngx_err_t err;
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
176 ngx_array_t vec;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
177 ngx_event_t *rev;
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
178 struct iovec *iov, iovs[NGX_IOVS];
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
179
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
180 prev = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
181 iov = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
182 size = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
183
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
184 vec.elts = iovs;
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
185 vec.nelts = 0;
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
186 vec.size = sizeof(struct iovec);
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
187 vec.nalloc = NGX_IOVS;
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
188 vec.pool = c->pool;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
189
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
190 /* coalesce the neighbouring bufs */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
191
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
192 while (chain) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
193 if (prev == chain->buf->last) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
194 iov->iov_len += chain->buf->end - chain->buf->last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
195
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
196 } else {
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
197 iov = ngx_array_push(&vec);
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
198 if (iov == NULL) {
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
199 return NGX_ERROR;
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
200 }
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
201
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents: 50
diff changeset
202 iov->iov_base = (void *) chain->buf->last;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
203 iov->iov_len = chain->buf->end - chain->buf->last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
204 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
205
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
206 size += chain->buf->end - chain->buf->last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
207 prev = chain->buf->end;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
208 chain = chain->next;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
209 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
210
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
211 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
212 "readv: %d:%d", vec.nelts, iov->iov_len);
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
213
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
214 rev = c->read;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
215
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
216 do {
50
72eb30262aac nginx 0.1.25
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
217 n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts);
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
218
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
219 if (n == 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
220 rev->ready = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
221 rev->eof = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
222
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
223 return n;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
224
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
225 } else if (n > 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
226
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
227 if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) {
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
228 rev->ready = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
229 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
230
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
231 return n;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
232 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
233
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
234 err = ngx_socket_errno;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
235
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
236 if (err == NGX_EAGAIN || err == NGX_EINTR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
237 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
238 "readv() not ready");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
239 n = NGX_AGAIN;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
240
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
241 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
242 n = ngx_connection_error(c, err, "readv() failed");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
243 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
244 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
245
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
246 } while (err == NGX_EINTR);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
247
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
248 rev->ready = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
249
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
250 if (n == NGX_ERROR){
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
251 c->read->error = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
252 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
253
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
254 return n;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
255 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
256
18
6f8b0dc0f8dd nginx 0.1.9
Igor Sysoev <http://sysoev.ru>
parents: 4
diff changeset
257 #endif /* NGX_HAVE_KQUEUE */