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