Mercurial > hg > nginx
comparison src/os/win32/ngx_wsasend.c @ 2725:d43d73277c5c
Win32 master/workers model
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 20 Apr 2009 06:08:47 +0000 |
parents | |
children | d620f497c50f |
comparison
equal
deleted
inserted
replaced
2724:9fd2f12fee0a | 2725:d43d73277c5c |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_event.h> | |
10 | |
11 | |
12 ssize_t | |
13 ngx_wsasend(ngx_connection_t *c, u_char *buf, size_t size) | |
14 { | |
15 int n; | |
16 u_long sent; | |
17 ngx_err_t err; | |
18 ngx_event_t *wev; | |
19 WSABUF wsabuf; | |
20 | |
21 wev = c->write; | |
22 | |
23 if (!wev->ready) { | |
24 return NGX_AGAIN; | |
25 } | |
26 | |
27 /* | |
28 * WSABUF must be 4-byte aligned otherwise | |
29 * WSASend() will return undocumented WSAEINVAL error. | |
30 */ | |
31 | |
32 wsabuf.buf = (char *) buf; | |
33 wsabuf.len = size; | |
34 | |
35 sent = 0; | |
36 | |
37 n = WSASend(c->fd, &wsabuf, 1, &sent, 0, NULL, NULL); | |
38 | |
39 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
40 "WSASend: fd:%d, %d, %ul of %uz", c->fd, n, sent, size); | |
41 | |
42 if (n == 0) { | |
43 if (sent < size) { | |
44 wev->ready = 0; | |
45 } | |
46 | |
47 c->sent += sent; | |
48 | |
49 return sent; | |
50 } | |
51 | |
52 err = ngx_socket_errno; | |
53 | |
54 if (err == WSAEWOULDBLOCK) { | |
55 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, "WSASend() not ready"); | |
56 return NGX_AGAIN; | |
57 } | |
58 | |
59 wev->error = 1; | |
60 ngx_connection_error(c, err, "WSASend() failed"); | |
61 | |
62 return NGX_ERROR; | |
63 } | |
64 | |
65 | |
66 ssize_t | |
67 ngx_overlapped_wsasend(ngx_connection_t *c, u_char *buf, size_t size) | |
68 { | |
69 int n; | |
70 u_long sent; | |
71 ngx_err_t err; | |
72 ngx_event_t *wev; | |
73 LPWSAOVERLAPPED ovlp; | |
74 WSABUF wsabuf; | |
75 | |
76 wev = c->write; | |
77 | |
78 if (!wev->ready) { | |
79 return NGX_AGAIN; | |
80 } | |
81 | |
82 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
83 "wev->complete: %d", wev->complete); | |
84 | |
85 if (!wev->complete) { | |
86 | |
87 /* post the overlapped WSASend() */ | |
88 | |
89 /* | |
90 * WSABUFs must be 4-byte aligned otherwise | |
91 * WSASend() will return undocumented WSAEINVAL error. | |
92 */ | |
93 | |
94 wsabuf.buf = (char *) buf; | |
95 wsabuf.len = size; | |
96 | |
97 sent = 0; | |
98 | |
99 ovlp = (LPWSAOVERLAPPED) &c->write->ovlp; | |
100 ngx_memzero(ovlp, sizeof(WSAOVERLAPPED)); | |
101 | |
102 n = WSASend(c->fd, &wsabuf, 1, &sent, 0, ovlp, NULL); | |
103 | |
104 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
105 "WSASend: fd:%d, %d, %ul of %uz", c->fd, n, sent, size); | |
106 | |
107 wev->complete = 0; | |
108 | |
109 if (n == 0) { | |
110 if (ngx_event_flags & NGX_USE_IOCP_EVENT) { | |
111 | |
112 /* | |
113 * if a socket was bound with I/O completion port then | |
114 * GetQueuedCompletionStatus() would anyway return its status | |
115 * despite that WSASend() was already complete | |
116 */ | |
117 | |
118 wev->active = 1; | |
119 return NGX_AGAIN; | |
120 } | |
121 | |
122 if (sent < size) { | |
123 wev->ready = 0; | |
124 } | |
125 | |
126 c->sent += sent; | |
127 | |
128 return sent; | |
129 } | |
130 | |
131 err = ngx_socket_errno; | |
132 | |
133 if (err == WSA_IO_PENDING) { | |
134 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | |
135 "WSASend() posted"); | |
136 wev->active = 1; | |
137 return NGX_AGAIN; | |
138 } | |
139 | |
140 wev->error = 1; | |
141 ngx_connection_error(c, err, "WSASend() failed"); | |
142 | |
143 return NGX_ERROR; | |
144 } | |
145 | |
146 /* the overlapped WSASend() complete */ | |
147 | |
148 wev->complete = 0; | |
149 wev->active = 0; | |
150 | |
151 if (ngx_event_flags & NGX_USE_IOCP_EVENT) { | |
152 | |
153 if (wev->ovlp.error) { | |
154 ngx_connection_error(c, wev->ovlp.error, "WSASend() failed"); | |
155 return NGX_ERROR; | |
156 } | |
157 | |
158 sent = wev->available; | |
159 | |
160 } else { | |
161 if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &wev->ovlp, | |
162 &sent, 0, NULL) | |
163 == 0) | |
164 { | |
165 ngx_connection_error(c, ngx_socket_errno, | |
166 "WSASend() or WSAGetOverlappedResult() failed"); | |
167 | |
168 return NGX_ERROR; | |
169 } | |
170 } | |
171 | |
172 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
173 "WSAGetOverlappedResult: fd:%d, %ul of %uz", | |
174 c->fd, sent, size); | |
175 | |
176 if (sent < size) { | |
177 wev->ready = 0; | |
178 } | |
179 | |
180 c->sent += sent; | |
181 | |
182 return sent; | |
183 } |