comparison src/os/win32/ngx_udp_wsarecv.c @ 1689:0b592a68aade

ngx_udp_recv()
author Igor Sysoev <igor@sysoev.ru>
date Mon, 03 Dec 2007 16:46:46 +0000
parents src/os/win32/ngx_wsarecv.c@e438ec9e736a
children 88987e52be42
comparison
equal deleted inserted replaced
1688:bd85a95d60c6 1689:0b592a68aade
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_udp_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
14 {
15 int rc;
16 u_long bytes, flags;
17 WSABUF wsabuf[1];
18 ngx_err_t err;
19 ngx_event_t *rev;
20
21 wsabuf[0].buf = (char *) buf;
22 wsabuf[0].len = size;
23 flags = 0;
24 bytes = 0;
25
26 rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, NULL, NULL);
27
28 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
29 "WSARecv: fd:%d rc:%d %ul of %z", c->fd, rc, bytes, size);
30
31 rev = c->read;
32
33 if (rc == -1) {
34 rev->ready = 0;
35 err = ngx_socket_errno;
36
37 if (err == WSAEWOULDBLOCK) {
38 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
39 "WSARecv() not ready");
40 return NGX_AGAIN;
41 }
42
43 rev->error = 1;
44 ngx_connection_error(c, err, "WSARecv() failed");
45
46 return NGX_ERROR;
47 }
48
49 return bytes;
50 }
51
52
53 ssize_t
54 ngx_udp_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
55 {
56 int rc;
57 u_long bytes, flags;
58 WSABUF wsabuf[1];
59 ngx_err_t err;
60 ngx_event_t *rev;
61 LPWSAOVERLAPPED ovlp;
62
63 rev = c->read;
64
65 if (!rev->ready) {
66 ngx_log_error(NGX_LOG_ALERT, c->log, 0, "second wsa post");
67 return NGX_AGAIN;
68 }
69
70 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
71 "rev->complete: %d", rev->complete);
72
73 if (rev->complete) {
74 rev->complete = 0;
75
76 if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
77 if (rev->ovlp.error) {
78 ngx_connection_error(c, rev->ovlp.error, "WSARecv() failed");
79 return NGX_ERROR;
80 }
81
82 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
83 "WSARecv ovlp: fd:%d %ul of %z",
84 c->fd, rev->available, size);
85
86 return rev->available;
87 }
88
89 if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &rev->ovlp,
90 &bytes, 0, NULL) == 0) {
91 ngx_connection_error(c, ngx_socket_errno,
92 "WSARecv() or WSAGetOverlappedResult() failed");
93 return NGX_ERROR;
94 }
95
96 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
97 "WSARecv: fd:%d %ul of %z", c->fd, bytes, size);
98
99 return bytes;
100 }
101
102 ovlp = (LPWSAOVERLAPPED) &rev->ovlp;
103 ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
104 wsabuf[0].buf = (char *) buf;
105 wsabuf[0].len = size;
106 flags = 0;
107 bytes = 0;
108
109 rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL);
110
111 rev->complete = 0;
112
113 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
114 "WSARecv ovlp: fd:%d rc:%d %ul of %z",
115 c->fd, rc, bytes, size);
116
117 if (rc == -1) {
118 err = ngx_socket_errno;
119 if (err == WSA_IO_PENDING) {
120 rev->active = 1;
121 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
122 "WSARecv() posted");
123 return NGX_AGAIN;
124 }
125
126 rev->error = 1;
127 ngx_connection_error(c, err, "WSARecv() failed");
128 return NGX_ERROR;
129 }
130
131 if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
132
133 /*
134 * if a socket was bound with I/O completion port
135 * then GetQueuedCompletionStatus() would anyway return its status
136 * despite that WSARecv() was already complete
137 */
138
139 rev->active = 1;
140 return NGX_AGAIN;
141 }
142
143 rev->active = 0;
144
145 return bytes;
146 }