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 }