comparison src/os/unix/ngx_readv_chain.c @ 290:87e73f067470

nginx-0.0.2-2004-03-16-10:10:12 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 16 Mar 2004 07:10:12 +0000
parents 70e1c7d2b83d
children 00c5660d2707
comparison
equal deleted inserted replaced
289:0750faf8d7e3 290:87e73f067470
3 #include <ngx_core.h> 3 #include <ngx_core.h>
4 #include <ngx_event.h> 4 #include <ngx_event.h>
5 5
6 6
7 #if (HAVE_KQUEUE) 7 #if (HAVE_KQUEUE)
8
9 ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
10 {
11 u_char *prev;
12 ssize_t n, size;
13 struct iovec *iov;
14 ngx_err_t err;
15 ngx_array_t io;
16 ngx_event_t *rev;
17
18 rev = c->read;
19
20 if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
21 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
22 "readv: eof:%d, avail:%d, err:%d",
23 rev->kq_eof, rev->available, rev->kq_errno);
24
25 if (rev->available == 0) {
26 if (rev->kq_eof) {
27 rev->ready = 0;
28 rev->eof = 1;
29
30 ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
31 "kevent() reported about an closed connection");
32
33 if (rev->kq_errno) {
34 rev->error = 1;
35 ngx_set_socket_errno(rev->kq_errno);
36 return NGX_ERROR;
37 }
38
39 return 0;
40
41 } else {
42 return NGX_AGAIN;
43 }
44 }
45 }
46
47 prev = NULL;
48 iov = NULL;
49 size = 0;
50
51 ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_ERROR);
52
53 /* coalesce the neighbouring hunks */
54
55 while (chain) {
56 if (prev == chain->hunk->last) {
57 iov->iov_len += chain->hunk->end - chain->hunk->last;
58
59 } else {
60 ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR);
61 iov->iov_base = (void *) chain->hunk->last;
62 iov->iov_len = chain->hunk->end - chain->hunk->last;
63 }
64
65 size += chain->hunk->end - chain->hunk->last;
66 prev = chain->hunk->end;
67 chain = chain->next;
68 }
69
70 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
71 "readv: %d:%d", io.nelts, iov->iov_len);
72
73 rev = c->read;
74
75 do {
76 n = readv(c->fd, (struct iovec *) io.elts, io.nelts);
77
78 if (n >= 0) {
79 if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
80 rev->available -= n;
81
82 /*
83 * rev->available can be negative here because some additional
84 * bytes can be received between kevent() and recv()
85 */
86
87 if (rev->available <= 0) {
88 if (!rev->kq_eof) {
89 rev->ready = 0;
90 }
91
92 if (rev->available < 0) {
93 rev->available = 0;
94 }
95 }
96
97 return n;
98 }
99
100 if (n < size) {
101 rev->ready = 0;
102 }
103
104 if (n == 0) {
105 rev->eof = 1;
106 }
107
108 return n;
109 }
110
111 err = ngx_socket_errno;
112
113 if (err == NGX_EAGAIN || err == NGX_EINTR) {
114 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
115 "readv() not ready");
116 n = NGX_AGAIN;
117
118 } else {
119 n = ngx_connection_error(c, err, "readv() failed");
120 break;
121 }
122
123 } while (err == NGX_EINTR);
124
125 rev->ready = 0;
126
127 if (n == NGX_ERROR){
128 c->read->error = 1;
129 }
130
131 return n;
132 }
133
134 #else /* ! NAVE_KQUEUE */
8 135
9 ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain) 136 ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
10 { 137 {
11 char *prev; 138 char *prev;
12 ssize_t n, size; 139 ssize_t n, size;
13 struct iovec *iov; 140 struct iovec *iov;
14 ngx_err_t err; 141 ngx_err_t err;
15 ngx_array_t io; 142 ngx_array_t io;
16 ngx_event_t *rev; 143 ngx_event_t *rev;
17 144
18 rev = c->read;
19
20 if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
21 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
22 "readv: eof:%d, avail:%d, err:%d",
23 rev->kq_eof, rev->available, rev->kq_errno);
24
25 if (rev->available == 0) {
26 if (rev->kq_eof) {
27 rev->ready = 0;
28 rev->eof = 1;
29
30 ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
31 "kevent() reported about an closed connection");
32
33 if (rev->kq_errno) {
34 rev->error = 1;
35 ngx_set_socket_errno(rev->kq_errno);
36 return NGX_ERROR;
37 }
38
39 return 0;
40
41 } else {
42 return NGX_AGAIN;
43 }
44 }
45 }
46
47 prev = NULL; 145 prev = NULL;
48 iov = NULL; 146 iov = NULL;
49 size = 0; 147 size = 0;
50 148
51 ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_ERROR); 149 ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_ERROR);
74 172
75 do { 173 do {
76 n = readv(c->fd, (struct iovec *) io.elts, io.nelts); 174 n = readv(c->fd, (struct iovec *) io.elts, io.nelts);
77 175
78 if (n >= 0) { 176 if (n >= 0) {
79 if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
80 rev->available -= n;
81
82 /*
83 * rev->available can be negative here because some additional
84 * bytes can be received between kevent() and recv()
85 */
86
87 if (rev->available <= 0) {
88 if (!rev->kq_eof) {
89 rev->ready = 0;
90 }
91
92 if (rev->available < 0) {
93 rev->available = 0;
94 }
95 }
96
97 return n;
98 }
99
100 if (n < size) { 177 if (n < size) {
101 rev->ready = 0; 178 rev->ready = 0;
102 } 179 }
103 180
104 if (n == 0) { 181 if (n == 0) {
129 } 206 }
130 207
131 return n; 208 return n;
132 } 209 }
133 210
134 #else /* ! NAVE_KQUEUE */
135
136 ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
137 {
138 char *prev;
139 ssize_t n, size;
140 struct iovec *iov;
141 ngx_err_t err;
142 ngx_array_t io;
143 ngx_event_t *rev;
144
145 prev = NULL;
146 iov = NULL;
147 size = 0;
148
149 ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_ERROR);
150
151 /* coalesce the neighbouring hunks */
152
153 while (chain) {
154 if (prev == chain->hunk->last) {
155 iov->iov_len += chain->hunk->end - chain->hunk->last;
156
157 } else {
158 ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR);
159 iov->iov_base = chain->hunk->last;
160 iov->iov_len = chain->hunk->end - chain->hunk->last;
161 }
162
163 size += chain->hunk->end - chain->hunk->last;
164 prev = chain->hunk->end;
165 chain = chain->next;
166 }
167
168 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
169 "readv: %d:%d", io.nelts, iov->iov_len);
170
171 rev = c->read;
172
173 do {
174 n = readv(c->fd, (struct iovec *) io.elts, io.nelts);
175
176 if (n >= 0) {
177 if (n < size) {
178 rev->ready = 0;
179 }
180
181 if (n == 0) {
182 rev->eof = 1;
183 }
184
185 return n;
186 }
187
188 err = ngx_socket_errno;
189
190 if (err == NGX_EAGAIN || err == NGX_EINTR) {
191 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
192 "readv() not ready");
193 n = NGX_AGAIN;
194
195 } else {
196 n = ngx_connection_error(c, err, "readv() failed");
197 break;
198 }
199
200 } while (err == NGX_EINTR);
201
202 rev->ready = 0;
203
204 if (n == NGX_ERROR){
205 c->read->error = 1;
206 }
207
208 return n;
209 }
210
211 #endif /* NAVE_KQUEUE */ 211 #endif /* NAVE_KQUEUE */