Mercurial > hg > nginx
comparison src/os/win32/ngx_wsasend_chain.c @ 461:a88a3e4e158f release-0.1.5
nginx-0.1.5-RELEASE import
*) Bugfix: on Solaris and Linux there may be too many "recvmsg()
returned not enough data" alerts.
*) Bugfix: there were the "writev() failed (22: Invalid argument)"
errors on Solaris in proxy mode without sendfile. On other platforms
that do not support sendfile at all the process got caught in an
endless loop.
*) Bugfix: segmentation fault on Solaris in proxy mode and using
sendfile.
*) Bugfix: segmentation fault on Solaris.
*) Bugfix: on-line upgrade did not work on Linux.
*) Bugfix: the ngx_http_autoindex_module module did not escape the
spaces, the quotes, and the percent signs in the directory listing.
*) Change: the decrease of the copy operations.
*) Feature: the userid_p3p directive.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 11 Nov 2004 14:07:14 +0000 |
parents | 42d11f017717 |
children | 8e8f3af115b5 |
comparison
equal
deleted
inserted
replaced
460:5f8319142dfc | 461:a88a3e4e158f |
---|---|
5 | 5 |
6 | 6 |
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 | |
11 | |
12 #define NGX_WSABUFS 8 | |
10 | 13 |
11 | 14 |
12 ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, | 15 ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, |
13 off_t limit) | 16 off_t limit) |
14 { | 17 { |
15 int rc; | 18 int rc; |
16 u_char *prev; | 19 u_char *prev; |
17 size_t size; | 20 u_long size, sent, send, sprev; |
18 u_long sent; | 21 ngx_uint_t complete; |
19 LPWSABUF wsabuf; | |
20 ngx_err_t err; | 22 ngx_err_t err; |
21 ngx_event_t *wev; | 23 ngx_event_t *wev; |
22 ngx_array_t wsabufs; | 24 ngx_array_t vec; |
25 LPWSABUF wsabuf; | |
26 WSABUF wsabufs[NGX_WSABUFS]; | |
23 ngx_chain_t *cl; | 27 ngx_chain_t *cl; |
24 | 28 |
25 wev = c->write; | 29 wev = c->write; |
26 | 30 |
27 if (!wev->ready) { | 31 if (!wev->ready) { |
28 return in; | 32 return in; |
29 } | 33 } |
34 | |
35 send = 0; | |
36 complete = 0; | |
30 | 37 |
31 /* | 38 /* |
32 * WSABUFs must be 4-byte aligned otherwise | 39 * WSABUFs must be 4-byte aligned otherwise |
33 * WSASend() will return undocumented WSAEINVAL error. | 40 * WSASend() will return undocumented WSAEINVAL error. |
34 */ | 41 */ |
35 | 42 |
36 ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR); | 43 vec.elts = wsabufs; |
37 | 44 vec.size = sizeof(WSABUF); |
38 prev = NULL; | 45 vec.nalloc = NGX_WSABUFS; |
39 wsabuf = NULL; | 46 vec.pool = c->pool; |
40 | 47 |
41 /* create the WSABUF and coalesce the neighbouring bufs */ | 48 for ( ;; ) { |
42 | 49 prev = NULL; |
43 for (cl = in; cl; cl = cl->next) { | 50 wsabuf = NULL; |
44 | 51 sprev = send; |
45 if (prev == cl->buf->pos) { | 52 |
46 wsabuf->len += cl->buf->last - cl->buf->pos; | 53 vec.nelts = 0; |
54 | |
55 /* create the WSABUF and coalesce the neighbouring bufs */ | |
56 | |
57 for (cl = in; | |
58 cl && vec.nelts < ngx_max_wsabufs && send < limit; | |
59 cl = cl->next) | |
60 { | |
61 if (ngx_buf_special(cl->buf)) { | |
62 continue; | |
63 } | |
64 | |
65 size = cl->buf->last - cl->buf->pos; | |
66 | |
67 if (send + size > limit) { | |
68 size = (u_long) (limit - send); | |
69 } | |
70 | |
71 if (prev == cl->buf->pos) { | |
72 wsabuf->len += cl->buf->last - cl->buf->pos; | |
73 | |
74 } else { | |
75 if (!(wsabuf = ngx_array_push(&vec))) { | |
76 return NGX_CHAIN_ERROR; | |
77 } | |
78 | |
79 wsabuf->buf = (char *) cl->buf->pos; | |
80 wsabuf->len = cl->buf->last - cl->buf->pos; | |
81 } | |
82 | |
47 prev = cl->buf->last; | 83 prev = cl->buf->last; |
48 | 84 send += size; |
49 } else { | 85 } |
50 ngx_test_null(wsabuf, ngx_push_array(&wsabufs), NGX_CHAIN_ERROR); | 86 |
51 wsabuf->buf = (char *) cl->buf->pos; | 87 sent = 0; |
52 wsabuf->len = cl->buf->last - cl->buf->pos; | 88 |
53 prev = cl->buf->last; | 89 rc = WSASend(c->fd, vec.elts, vec.nelts, &sent, 0, NULL, NULL); |
54 } | 90 |
55 } | 91 if (rc == -1) { |
56 | 92 err = ngx_errno; |
57 rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, NULL, NULL); | 93 |
58 | 94 if (err == WSAEWOULDBLOCK) { |
59 if (rc == -1) { | 95 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, |
60 err = ngx_errno; | 96 "WSASend() not ready"); |
61 | 97 |
62 if (err == WSAEWOULDBLOCK) { | 98 } else { |
63 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | 99 wev->error = 1; |
64 "WSASend() not ready"); | 100 ngx_connection_error(c, err, "WSASend() failed"); |
101 return NGX_CHAIN_ERROR; | |
102 } | |
103 } | |
104 | |
105 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
106 "WSASend: fd:%d, s:%ul", c->fd, sent); | |
107 | |
108 if (send - sprev == sent) { | |
109 complete = 1; | |
110 } | |
111 | |
112 c->sent += sent; | |
113 | |
114 for (cl = in; cl && sent > 0; cl = cl->next) { | |
115 if (ngx_buf_special(cl->buf)) { | |
116 continue; | |
117 } | |
118 | |
119 if (sent == 0) { | |
120 break; | |
121 } | |
122 | |
123 size = cl->buf->last - cl->buf->pos; | |
124 | |
125 if (sent >= size) { | |
126 sent -= size; | |
127 cl->buf->pos = cl->buf->last; | |
128 | |
129 continue; | |
130 } | |
131 | |
132 cl->buf->pos += sent; | |
133 | |
134 break; | |
135 } | |
136 | |
137 if (!complete) { | |
65 wev->ready = 0; | 138 wev->ready = 0; |
66 return in; | 139 return cl; |
67 | 140 } |
68 } else { | 141 |
69 wev->error = 1; | 142 if (send >= limit || cl == NULL) { |
70 ngx_connection_error(c, err, "WSASend() failed"); | 143 return cl; |
71 return NGX_CHAIN_ERROR; | 144 } |
72 } | 145 |
73 } | 146 in = cl; |
74 | 147 } |
75 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "WSASend: %d", sent); | |
76 | |
77 c->sent += sent; | |
78 | |
79 for (cl = in; cl && sent > 0; cl = cl->next) { | |
80 | |
81 size = cl->buf->last - cl->buf->pos; | |
82 | |
83 if (sent >= size) { | |
84 sent -= size; | |
85 | |
86 if (ngx_buf_in_memory(cl->buf)) { | |
87 cl->buf->pos = cl->buf->last; | |
88 } | |
89 | |
90 continue; | |
91 } | |
92 | |
93 if (ngx_buf_in_memory(cl->buf)) { | |
94 cl->buf->pos += sent; | |
95 } | |
96 | |
97 break; | |
98 } | |
99 | |
100 if (cl) { | |
101 wev->ready = 0; | |
102 } | |
103 | |
104 return cl; | |
105 } | 148 } |
106 | 149 |
107 | 150 |
108 ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, | 151 ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, |
109 off_t limit) | 152 off_t limit) |
110 { | 153 { |
111 int rc; | 154 int rc; |
112 u_char *prev; | 155 u_char *prev; |
113 size_t size; | 156 size_t size; |
114 u_long sent; | 157 u_long send, sent; |
115 LPWSABUF wsabuf; | 158 LPWSABUF wsabuf; |
116 ngx_err_t err; | 159 ngx_err_t err; |
117 ngx_event_t *wev; | 160 ngx_event_t *wev; |
118 ngx_array_t wsabufs; | 161 ngx_array_t vec; |
119 ngx_chain_t *cl; | 162 ngx_chain_t *cl; |
120 LPWSAOVERLAPPED ovlp; | 163 LPWSAOVERLAPPED ovlp; |
164 WSABUF wsabufs[NGX_WSABUFS]; | |
121 | 165 |
122 wev = c->write; | 166 wev = c->write; |
123 | 167 |
124 if (!wev->ready) { | 168 if (!wev->ready) { |
125 return in; | 169 return in; |
126 } | 170 } |
171 | |
172 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
173 "wev->complete: %d", wev->complete); | |
127 | 174 |
128 if (!wev->complete) { | 175 if (!wev->complete) { |
129 | 176 |
130 /* post the overlapped WSASend() */ | 177 /* post the overlapped WSASend() */ |
131 | 178 |
132 /* | 179 /* |
133 * WSABUFs must be 4-byte aligned otherwise | 180 * WSABUFs must be 4-byte aligned otherwise |
134 * WSASend() will return undocumented WSAEINVAL error. | 181 * WSASend() will return undocumented WSAEINVAL error. |
135 */ | 182 */ |
136 | 183 |
137 ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR); | 184 vec.elts = wsabufs; |
138 | 185 vec.nelts = 0; |
186 vec.size = sizeof(WSABUF); | |
187 vec.nalloc = NGX_WSABUFS; | |
188 vec.pool = c->pool; | |
189 | |
190 send = 0; | |
139 prev = NULL; | 191 prev = NULL; |
140 wsabuf = NULL; | 192 wsabuf = NULL; |
141 | 193 |
142 /* create the WSABUF and coalesce the neighbouring bufs */ | 194 /* create the WSABUF and coalesce the neighbouring bufs */ |
143 | 195 |
144 for (cl = in; cl; cl = cl->next) { | 196 for (cl = in; |
197 cl && vec.nelts < ngx_max_wsabufs && send < limit; | |
198 cl = cl->next) | |
199 { | |
200 if (ngx_buf_special(cl->buf)) { | |
201 continue; | |
202 } | |
203 | |
204 size = cl->buf->last - cl->buf->pos; | |
205 | |
206 if (send + size > limit) { | |
207 size = (u_long) (limit - send); | |
208 } | |
145 | 209 |
146 if (prev == cl->buf->pos) { | 210 if (prev == cl->buf->pos) { |
147 wsabuf->len += cl->buf->last - cl->buf->pos; | 211 wsabuf->len += cl->buf->last - cl->buf->pos; |
148 prev = cl->buf->last; | 212 |
149 | |
150 } else { | 213 } else { |
151 ngx_test_null(wsabuf, ngx_push_array(&wsabufs), | 214 if (!(wsabuf = ngx_array_push(&vec))) { |
152 NGX_CHAIN_ERROR); | 215 return NGX_CHAIN_ERROR; |
216 } | |
217 | |
153 wsabuf->buf = (char *) cl->buf->pos; | 218 wsabuf->buf = (char *) cl->buf->pos; |
154 wsabuf->len = cl->buf->last - cl->buf->pos; | 219 wsabuf->len = cl->buf->last - cl->buf->pos; |
155 prev = cl->buf->last; | 220 } |
156 } | 221 |
222 prev = cl->buf->last; | |
223 send += size; | |
157 } | 224 } |
158 | 225 |
159 ovlp = (LPWSAOVERLAPPED) &c->write->ovlp; | 226 ovlp = (LPWSAOVERLAPPED) &c->write->ovlp; |
160 ngx_memzero(ovlp, sizeof(WSAOVERLAPPED)); | 227 ngx_memzero(ovlp, sizeof(WSAOVERLAPPED)); |
161 | 228 |
162 rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, ovlp, NULL); | 229 rc = WSASend(c->fd, vec.elts, vec.nelts, &sent, 0, ovlp, NULL); |
163 | 230 |
164 wev->complete = 0; | 231 wev->complete = 0; |
165 | 232 |
166 if (rc == -1) { | 233 if (rc == -1) { |
167 err = ngx_errno; | 234 err = ngx_errno; |
168 | 235 |
169 if (err == WSA_IO_PENDING) { | 236 if (err == WSA_IO_PENDING) { |
237 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | |
238 "WSASend() posted"); | |
170 wev->active = 1; | 239 wev->active = 1; |
171 return in; | 240 return in; |
172 | 241 |
173 } else { | 242 } else { |
174 wev->error = 1; | 243 wev->error = 1; |
185 */ | 254 */ |
186 | 255 |
187 wev->active = 1; | 256 wev->active = 1; |
188 return in; | 257 return in; |
189 } | 258 } |
259 | |
260 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
261 "WSASend: fd:%d, s:%ul", c->fd, sent); | |
190 | 262 |
191 } else { | 263 } else { |
192 | 264 |
193 /* the overlapped WSASend() complete */ | 265 /* the overlapped WSASend() complete */ |
194 | 266 |
212 return NGX_CHAIN_ERROR; | 284 return NGX_CHAIN_ERROR; |
213 } | 285 } |
214 } | 286 } |
215 } | 287 } |
216 | 288 |
217 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "WSASend: %d", sent); | 289 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
290 "WSASend ovlp: fd:%d, s:%ul", c->fd, sent); | |
218 | 291 |
219 c->sent += sent; | 292 c->sent += sent; |
220 | 293 |
221 for (cl = in; cl && sent > 0; cl = cl->next) { | 294 for (cl = in; cl && sent > 0; cl = cl->next) { |
295 if (ngx_buf_special(cl->buf)) { | |
296 continue; | |
297 } | |
298 | |
299 if (sent == 0) { | |
300 break; | |
301 } | |
222 | 302 |
223 size = cl->buf->last - cl->buf->pos; | 303 size = cl->buf->last - cl->buf->pos; |
224 | 304 |
225 if (sent >= size) { | 305 if (sent >= size) { |
226 sent -= size; | 306 sent -= size; |
227 | 307 cl->buf->pos = cl->buf->last; |
228 if (ngx_buf_in_memory(cl->buf)) { | |
229 cl->buf->pos = cl->buf->last; | |
230 } | |
231 | 308 |
232 continue; | 309 continue; |
233 } | 310 } |
234 | 311 |
235 if (ngx_buf_in_memory(cl->buf)) { | 312 cl->buf->pos += sent; |
236 cl->buf->pos += sent; | |
237 } | |
238 | 313 |
239 break; | 314 break; |
240 } | 315 } |
241 | 316 |
242 if (cl) { | 317 if (cl) { |