Mercurial > hg > nginx
comparison src/os/win32/ngx_wsasend_chain.c @ 103:6dfda4cf5200
nginx-0.0.1-2003-06-11-19:28:34 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 11 Jun 2003 15:28:34 +0000 |
parents | |
children | ef8c87afcfc5 |
comparison
equal
deleted
inserted
replaced
102:7e86d028d8f0 | 103:6dfda4cf5200 |
---|---|
1 | |
2 #include <ngx_config.h> | |
3 #include <ngx_core.h> | |
4 #include <ngx_event.h> | |
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 *ce; | |
17 LPWSAOVERLAPPED ovlp; | |
18 | |
19 #if 0 | |
20 | |
21 iocp: | |
22 if ready | |
23 get result | |
24 update chain | |
25 return if done; | |
26 wsasend | |
27 | |
28 non-block | |
29 for ( ;; ) { | |
30 wsasend | |
31 if no again | |
32 update chain | |
33 return if done; | |
34 } | |
35 | |
36 | |
37 for ( ;; ) { | |
38 | |
39 make buffers and limit data for both ovlp and nonblocked, | |
40 configured in events module | |
41 | |
42 if (iocp && ready) { | |
43 get result | |
44 | |
45 } else { | |
46 if (file) | |
47 transmitfile | |
48 else | |
49 wsasend | |
50 | |
51 if (iocp) | |
52 return chain | |
53 return chain if again | |
54 here is result | |
55 } | |
56 | |
57 if (result) | |
58 update chain; | |
59 return chain if done | |
60 } | |
61 } | |
62 | |
63 | |
64 #endif | |
65 | |
66 wev = c->write; | |
67 | |
68 if (((ngx_event_flags & NGX_HAVE_AIO_EVENT) && !wev->ready) | |
69 || ((ngx_event_flags & NGX_HAVE_AIO_EVENT) == 0)) | |
70 { | |
71 /* | |
72 * WSABUFs must be 4-byte aligned otherwise | |
73 * WSASend() will return undocumented WSAEINVAL error. | |
74 */ | |
75 | |
76 ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR); | |
77 | |
78 prev = NULL; | |
79 wsabuf = NULL; | |
80 | |
81 /* create the WSABUF and coalesce the neighbouring chain entries */ | |
82 for (ce = in; ce; ce = ce->next) { | |
83 | |
84 if (prev == ce->hunk->pos) { | |
85 wsabuf->len += ce->hunk->last - ce->hunk->pos; | |
86 prev = ce->hunk->last; | |
87 | |
88 } else { | |
89 ngx_test_null(wsabuf, ngx_push_array(&wsabufs), | |
90 NGX_CHAIN_ERROR); | |
91 wsabuf->buf = ce->hunk->pos; | |
92 wsabuf->len = ce->hunk->last - ce->hunk->pos; | |
93 prev = ce->hunk->last; | |
94 } | |
95 } | |
96 | |
97 if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { | |
98 ovlp = (LPWSAOVERLAPPED) &c->write->ovlp; | |
99 ngx_memzero(ovlp, sizeof(WSAOVERLAPPED)); | |
100 | |
101 } else { | |
102 ovlp = NULL; | |
103 } | |
104 | |
105 rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, ovlp, NULL); | |
106 | |
107 if (rc == -1) { | |
108 err = ngx_errno; | |
109 if (err == WSA_IO_PENDING) { | |
110 sent = 0; | |
111 | |
112 } else if (err == WSAEWOULDBLOCK) { | |
113 sent = 0; | |
114 ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() EAGAIN"); | |
115 | |
116 } else { | |
117 ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSASend() failed"); | |
118 return NGX_CHAIN_ERROR; | |
119 } | |
120 | |
121 } else { | |
122 | |
123 if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) { | |
124 | |
125 /* | |
126 * If a socket was bound with I/O completion port then | |
127 * GetQueuedCompletionStatus() would anyway return its status | |
128 * despite that WSASend() was already completed. | |
129 */ | |
130 | |
131 sent = 0; | |
132 } | |
133 } | |
134 | |
135 } else { | |
136 if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) { | |
137 wev->ready = 0; | |
138 | |
139 /* the overlapped WSASend() completed */ | |
140 | |
141 if (wev->ovlp.error) { | |
142 ngx_log_error(NGX_LOG_ERR, c->log, wev->ovlp.error, | |
143 "WSASend() failed"); | |
144 return NGX_CHAIN_ERROR; | |
145 } | |
146 | |
147 sent = wev->available; | |
148 } | |
149 } | |
150 | |
151 #if (NGX_DEBUG_WRITE_CHAIN) | |
152 ngx_log_debug(c->log, "WSASend(): %d" _ sent); | |
153 #endif | |
154 | |
155 c->sent += sent; | |
156 | |
157 for (ce = in; ce && sent > 0; ce = ce->next) { | |
158 | |
159 size = ce->hunk->last - ce->hunk->pos; | |
160 | |
161 if (sent >= size) { | |
162 sent -= size; | |
163 | |
164 if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { | |
165 ce->hunk->pos = ce->hunk->last; | |
166 } | |
167 | |
168 continue; | |
169 } | |
170 | |
171 if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { | |
172 ce->hunk->pos += sent; | |
173 } | |
174 | |
175 break; | |
176 } | |
177 | |
178 ngx_destroy_array(&wsabufs); | |
179 | |
180 return ce; | |
181 } |