Mercurial > hg > nginx
comparison src/os/win32/ngx_wsasend_chain.c @ 184:1bf718ce0dde
nginx-0.0.1-2003-11-14-10:20:34 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 14 Nov 2003 07:20:34 +0000 |
parents | ef8c87afcfc5 |
children | 70e1c7d2b83d |
comparison
equal
deleted
inserted
replaced
183:4c698194c56d | 184:1bf718ce0dde |
---|---|
1 | 1 |
2 #include <ngx_config.h> | 2 #include <ngx_config.h> |
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_event.h> | 4 #include <ngx_event.h> |
5 | 5 |
6 | |
7 ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in) | |
8 { | |
9 int rc; | |
10 char *prev; | |
11 size_t size, sent; | |
12 LPWSABUF wsabuf; | |
13 ngx_err_t err; | |
14 ngx_event_t *wev; | |
15 ngx_array_t wsabufs; | |
16 ngx_chain_t *cl; | |
17 | |
18 wev = c->write; | |
19 | |
20 if (!wev->ready) { | |
21 return in; | |
22 } | |
23 | |
24 /* | |
25 * WSABUFs must be 4-byte aligned otherwise | |
26 * WSASend() will return undocumented WSAEINVAL error. | |
27 */ | |
28 | |
29 ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR); | |
30 | |
31 prev = NULL; | |
32 wsabuf = NULL; | |
33 | |
34 /* create the WSABUF and coalesce the neighbouring bufs */ | |
35 | |
36 for (cl = in; cl; cl = cl->next) { | |
37 | |
38 if (prev == cl->hunk->pos) { | |
39 wsabuf->len += cl->hunk->last - cl->hunk->pos; | |
40 prev = cl->hunk->last; | |
41 | |
42 } else { | |
43 ngx_test_null(wsabuf, ngx_push_array(&wsabufs), NGX_CHAIN_ERROR); | |
44 wsabuf->buf = cl->hunk->pos; | |
45 wsabuf->len = cl->hunk->last - cl->hunk->pos; | |
46 prev = cl->hunk->last; | |
47 } | |
48 } | |
49 | |
50 rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, NULL, NULL); | |
51 | |
52 if (rc == -1) { | |
53 err = ngx_errno; | |
54 | |
55 if (err == WSAEWOULDBLOCK) { | |
56 ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() EAGAIN"); | |
57 wev->ready = 0; | |
58 return in; | |
59 | |
60 } else { | |
61 wev->error = 1; | |
62 ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSASend() failed"); | |
63 return NGX_CHAIN_ERROR; | |
64 } | |
65 } | |
66 | |
67 #if (NGX_DEBUG_WRITE_CHAIN) | |
68 ngx_log_debug(c->log, "WSASend(): %d" _ sent); | |
69 #endif | |
70 | |
71 c->sent += sent; | |
72 | |
73 for (cl = in; cl && sent > 0; cl = cl->next) { | |
74 | |
75 size = cl->hunk->last - cl->hunk->pos; | |
76 | |
77 if (sent >= size) { | |
78 sent -= size; | |
79 | |
80 if (cl->hunk->type & NGX_HUNK_IN_MEMORY) { | |
81 cl->hunk->pos = cl->hunk->last; | |
82 } | |
83 | |
84 continue; | |
85 } | |
86 | |
87 if (cl->hunk->type & NGX_HUNK_IN_MEMORY) { | |
88 cl->hunk->pos += sent; | |
89 } | |
90 | |
91 break; | |
92 } | |
93 | |
94 if (cl) { | |
95 wev->ready = 0; | |
96 } | |
97 | |
98 return cl; | |
99 } | |
100 | |
101 | |
102 ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in) | |
103 { | |
104 int rc; | |
105 char *prev; | |
106 size_t size, sent; | |
107 LPWSABUF wsabuf; | |
108 ngx_err_t err; | |
109 ngx_event_t *wev; | |
110 ngx_array_t wsabufs; | |
111 ngx_chain_t *cl; | |
112 LPWSAOVERLAPPED ovlp; | |
113 | |
114 wev = c->write; | |
115 | |
116 if (!wev->ready) { | |
117 return in; | |
118 } | |
119 | |
120 if (!wev->complete) { | |
121 | |
122 /* post the overlapped WSASend() */ | |
123 | |
124 /* | |
125 * WSABUFs must be 4-byte aligned otherwise | |
126 * WSASend() will return undocumented WSAEINVAL error. | |
127 */ | |
128 | |
129 ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR); | |
130 | |
131 prev = NULL; | |
132 wsabuf = NULL; | |
133 | |
134 /* create the WSABUF and coalesce the neighbouring bufs */ | |
135 | |
136 for (cl = in; cl; cl = cl->next) { | |
137 | |
138 if (prev == cl->hunk->pos) { | |
139 wsabuf->len += cl->hunk->last - cl->hunk->pos; | |
140 prev = cl->hunk->last; | |
141 | |
142 } else { | |
143 ngx_test_null(wsabuf, ngx_push_array(&wsabufs), | |
144 NGX_CHAIN_ERROR); | |
145 wsabuf->buf = cl->hunk->pos; | |
146 wsabuf->len = cl->hunk->last - cl->hunk->pos; | |
147 prev = cl->hunk->last; | |
148 } | |
149 } | |
150 | |
151 ovlp = (LPWSAOVERLAPPED) &c->write->ovlp; | |
152 ngx_memzero(ovlp, sizeof(WSAOVERLAPPED)); | |
153 | |
154 rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, ovlp, NULL); | |
155 | |
156 wev->complete = 0; | |
157 | |
158 if (rc == -1) { | |
159 err = ngx_errno; | |
160 | |
161 if (err == WSA_IO_PENDING) { | |
162 wev->active = 1; | |
163 return in; | |
164 | |
165 } else { | |
166 wev->error = 1; | |
167 ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSASend() failed"); | |
168 return NGX_CHAIN_ERROR; | |
169 } | |
170 | |
171 } else if (ngx_event_flags & NGX_USE_IOCP_EVENT) { | |
172 | |
173 /* | |
174 * if a socket was bound with I/O completion port then | |
175 * GetQueuedCompletionStatus() would anyway return its status | |
176 * despite that WSASend() was already complete | |
177 */ | |
178 | |
179 wev->active = 1; | |
180 return in; | |
181 } | |
182 | |
183 } else { | |
184 | |
185 /* the overlapped WSASend() complete */ | |
186 | |
187 wev->complete = 0; | |
188 wev->active = 0; | |
189 | |
190 if (ngx_event_flags & NGX_USE_IOCP_EVENT) { | |
191 if (wev->ovlp.error) { | |
192 ngx_log_error(NGX_LOG_ERR, c->log, wev->ovlp.error, | |
193 "WSASend() failed"); | |
194 return NGX_CHAIN_ERROR; | |
195 } | |
196 | |
197 sent = wev->available; | |
198 | |
199 } else { | |
200 if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &wev->ovlp, | |
201 &sent, 0, NULL) == 0) { | |
202 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, | |
203 "WSASend() or WSAGetOverlappedResult() failed"); | |
204 | |
205 return NGX_CHAIN_ERROR; | |
206 } | |
207 } | |
208 } | |
209 | |
210 #if (NGX_DEBUG_WRITE_CHAIN) | |
211 ngx_log_debug(c->log, "WSASend(): %d" _ sent); | |
212 #endif | |
213 | |
214 c->sent += sent; | |
215 | |
216 for (cl = in; cl && sent > 0; cl = cl->next) { | |
217 | |
218 size = cl->hunk->last - cl->hunk->pos; | |
219 | |
220 if (sent >= size) { | |
221 sent -= size; | |
222 | |
223 if (cl->hunk->type & NGX_HUNK_IN_MEMORY) { | |
224 cl->hunk->pos = cl->hunk->last; | |
225 } | |
226 | |
227 continue; | |
228 } | |
229 | |
230 if (cl->hunk->type & NGX_HUNK_IN_MEMORY) { | |
231 cl->hunk->pos += sent; | |
232 } | |
233 | |
234 break; | |
235 } | |
236 | |
237 if (cl) { | |
238 wev->ready = 0; | |
239 | |
240 } else { | |
241 wev->ready = 1; | |
242 } | |
243 | |
244 return cl; | |
245 } | |
246 | |
247 | |
248 #if 0 | |
6 | 249 |
7 ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in) | 250 ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in) |
8 { | 251 { |
9 int rc; | 252 int rc; |
10 char *prev; | 253 char *prev; |
173 } | 416 } |
174 | 417 |
175 break; | 418 break; |
176 } | 419 } |
177 | 420 |
178 ngx_destroy_array(&wsabufs); | |
179 | |
180 return ce; | 421 return ce; |
181 } | 422 } |
423 | |
424 #endif |