Klaus Demo nginx / e67d461
ngx_udp_recv() Igor Sysoev 14 years ago
14 changed file(s) with 282 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
163163 src/os/unix/ngx_socket.c \
164164 src/os/unix/ngx_recv.c \
165165 src/os/unix/ngx_readv_chain.c \
166 src/os/unix/ngx_udp_recv.c \
166167 src/os/unix/ngx_send.c \
167168 src/os/unix/ngx_writev_chain.c \
168169 src/os/unix/ngx_channel.c \
228229 src/os/win32/ngx_socket.c \
229230 src/os/win32/ngx_wsarecv.c \
230231 src/os/win32/ngx_wsarecv_chain.c \
232 src/os/win32/ngx_udp_wsarecv.c \
231233 src/os/win32/ngx_wsasend_chain.c \
232234 src/os/win32/ngx_win32_init.c \
233235 src/os/win32/ngx_user.c \
825825 c = rev->data;
826826
827827 do {
828 n = ngx_recv(c, buf, NGX_RESOLVER_UDP_SIZE);
829
830 if (n == -1) {
828 n = ngx_udp_recv(c, buf, NGX_RESOLVER_UDP_SIZE);
829
830 if (n < 0) {
831831 return;
832832 }
833833
2727 ngx_os_io_t ngx_os_aio = {
2828 ngx_aio_read,
2929 ngx_aio_read_chain,
30 NULL,
3031 ngx_aio_write,
3132 ngx_aio_write_chain,
3233 0
8989 ngx_os_io_t ngx_iocp_io = {
9090 ngx_overlapped_wsarecv,
9191 NULL,
92 ngx_udp_overlapped_wsarecv,
9293 NULL,
9394 ngx_overlapped_wsasend_chain,
9495 0
428428
429429 #define ngx_recv ngx_io.recv
430430 #define ngx_recv_chain ngx_io.recv_chain
431 #define ngx_udp_recv ngx_io.udp_recv
431432 #define ngx_send ngx_io.send
432433 #define ngx_send_chain ngx_io.send_chain
433434
2929 static ngx_os_io_t ngx_freebsd_io = {
3030 ngx_unix_recv,
3131 ngx_readv_chain,
32 ngx_udp_unix_recv,
3233 ngx_unix_send,
3334 #if (NGX_HAVE_SENDFILE)
3435 ngx_freebsd_sendfile_chain,
1616 static ngx_os_io_t ngx_linux_io = {
1717 ngx_unix_recv,
1818 ngx_readv_chain,
19 ngx_udp_unix_recv,
1920 ngx_unix_send,
2021 #if (NGX_HAVE_SENDFILE)
2122 ngx_linux_sendfile_chain,
2424 typedef struct {
2525 ngx_recv_pt recv;
2626 ngx_recv_chain_pt recv_chain;
27 ngx_recv_pt udp_recv;
2728 ngx_send_pt send;
2829 ngx_send_chain_pt send_chain;
2930 ngx_uint_t flags;
4041
4142 ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size);
4243 ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry);
44 ssize_t ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size);
4345 ssize_t ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size);
4446 ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in,
4547 off_t limit);
2020 ngx_os_io_t ngx_os_io = {
2121 ngx_unix_recv,
2222 ngx_readv_chain,
23 ngx_udp_unix_recv,
2324 NULL,
2425 ngx_writev_chain,
2526 0
1515 static ngx_os_io_t ngx_solaris_io = {
1616 ngx_unix_recv,
1717 ngx_readv_chain,
18 ngx_udp_unix_recv,
1819 ngx_unix_send,
1920 #if (NGX_HAVE_SENDFILE)
2021 ngx_solaris_sendfilev_chain,
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #include <ngx_config.h>
7 #include <ngx_core.h>
8 #include <ngx_event.h>
9
10
11 #if (NGX_HAVE_KQUEUE)
12
13 ssize_t
14 ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
15 {
16 ssize_t n;
17 ngx_err_t err;
18 ngx_event_t *rev;
19
20 rev = c->read;
21
22 do {
23 n = recv(c->fd, buf, size, 0);
24
25 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
26 "recv: fd:%d %d of %d", c->fd, n, size);
27
28 if (n >= 0) {
29 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
30 rev->available -= n;
31
32 /*
33 * rev->available may be negative here because some additional
34 * bytes may be received between kevent() and recv()
35 */
36
37 if (rev->available <= 0) {
38 rev->ready = 0;
39 rev->available = 0;
40 }
41 }
42
43 return n;
44 }
45
46 err = ngx_socket_errno;
47
48 if (err == NGX_EAGAIN || err == NGX_EINTR) {
49 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
50 "recv() not ready");
51 n = NGX_AGAIN;
52
53 } else {
54 n = ngx_connection_error(c, err, "recv() failed");
55 break;
56 }
57
58 } while (err == NGX_EINTR);
59
60 rev->ready = 0;
61
62 if (n == NGX_ERROR){
63 rev->error = 1;
64 }
65
66 return n;
67 }
68
69 #else /* ! NGX_HAVE_KQUEUE */
70
71 ssize_t
72 ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
73 {
74 ssize_t n;
75 ngx_err_t err;
76 ngx_event_t *rev;
77
78 rev = c->read;
79
80 do {
81 n = recv(c->fd, buf, size, 0);
82
83 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
84 "recv: fd:%d %d of %d", c->fd, n, size);
85
86 if (n >= 0) {
87 return n;
88 }
89
90 err = ngx_socket_errno;
91
92 if (err == NGX_EAGAIN || err == NGX_EINTR) {
93 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
94 "recv() not ready");
95 n = NGX_AGAIN;
96
97 } else {
98 n = ngx_connection_error(c, err, "recv() failed");
99 break;
100 }
101
102 } while (err == NGX_EINTR);
103
104 rev->ready = 0;
105
106 if (n == NGX_ERROR){
107 rev->error = 1;
108 }
109
110 return n;
111 }
112
113 #endif /* NGX_HAVE_KQUEUE */
1919 typedef ssize_t (*ngx_recv_chain_pt)(ngx_connection_t *c, ngx_chain_t *in);
2020 typedef ssize_t (*ngx_send_pt)(ngx_connection_t *c, u_char *buf, size_t size);
2121 typedef ngx_chain_t *(*ngx_send_chain_pt)(ngx_connection_t *c, ngx_chain_t *in,
22 off_t limit);
22 off_t limit);
2323
2424 typedef struct {
2525 ngx_recv_pt recv;
2626 ngx_recv_chain_pt recv_chain;
27 ngx_recv_pt udp_recv;
2728 ngx_send_pt send;
2829 ngx_send_chain_pt send_chain;
2930 ngx_uint_t flags;
3536
3637 ssize_t ngx_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
3738 ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
39 ssize_t ngx_udp_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
40 ssize_t ngx_udp_overlapped_wsarecv(ngx_connection_t *c, u_char *buf,
41 size_t size);
3842 ssize_t ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain);
3943 ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
40 off_t limit);
44 off_t limit);
4145 ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
42 off_t limit);
46 off_t limit);
4347
4448
4549 extern ngx_os_io_t ngx_os_io;
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #include <ngx_config.h>
7 #include <ngx_core.h>
8 #include <ngx_event.h>
9
10
11 ssize_t
12 ngx_udp_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
13 {
14 int rc;
15 u_long bytes, flags;
16 WSABUF wsabuf[1];
17 ngx_err_t err;
18 ngx_event_t *rev;
19
20 wsabuf[0].buf = (char *) buf;
21 wsabuf[0].len = size;
22 flags = 0;
23 bytes = 0;
24
25 rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, NULL, NULL);
26
27 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
28 "WSARecv: fd:%d rc:%d %ul of %z", c->fd, rc, bytes, size);
29
30 rev = c->read;
31
32 if (rc == -1) {
33 rev->ready = 0;
34 err = ngx_socket_errno;
35
36 if (err == WSAEWOULDBLOCK) {
37 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
38 "WSARecv() not ready");
39 return NGX_AGAIN;
40 }
41
42 rev->error = 1;
43 ngx_connection_error(c, err, "WSARecv() failed");
44
45 return NGX_ERROR;
46 }
47
48 return bytes;
49 }
50
51
52 ssize_t
53 ngx_udp_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
54 {
55 int rc;
56 u_long bytes, flags;
57 WSABUF wsabuf[1];
58 ngx_err_t err;
59 ngx_event_t *rev;
60 LPWSAOVERLAPPED ovlp;
61
62 rev = c->read;
63
64 if (!rev->ready) {
65 ngx_log_error(NGX_LOG_ALERT, c->log, 0, "second wsa post");
66 return NGX_AGAIN;
67 }
68
69 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
70 "rev->complete: %d", rev->complete);
71
72 if (rev->complete) {
73 rev->complete = 0;
74
75 if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
76 if (rev->ovlp.error) {
77 ngx_connection_error(c, rev->ovlp.error, "WSARecv() failed");
78 return NGX_ERROR;
79 }
80
81 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
82 "WSARecv ovlp: fd:%d %ul of %z",
83 c->fd, rev->available, size);
84
85 return rev->available;
86 }
87
88 if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &rev->ovlp,
89 &bytes, 0, NULL) == 0) {
90 ngx_connection_error(c, ngx_socket_errno,
91 "WSARecv() or WSAGetOverlappedResult() failed");
92 return NGX_ERROR;
93 }
94
95 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
96 "WSARecv: fd:%d %ul of %z", c->fd, bytes, size);
97
98 return bytes;
99 }
100
101 ovlp = (LPWSAOVERLAPPED) &rev->ovlp;
102 ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
103 wsabuf[0].buf = (char *) buf;
104 wsabuf[0].len = size;
105 flags = 0;
106 bytes = 0;
107
108 rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL);
109
110 rev->complete = 0;
111
112 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
113 "WSARecv ovlp: fd:%d rc:%d %ul of %z",
114 c->fd, rc, bytes, size);
115
116 if (rc == -1) {
117 err = ngx_socket_errno;
118 if (err == WSA_IO_PENDING) {
119 rev->active = 1;
120 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
121 "WSARecv() posted");
122 return NGX_AGAIN;
123 }
124
125 rev->error = 1;
126 ngx_connection_error(c, err, "WSARecv() failed");
127 return NGX_ERROR;
128 }
129
130 if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
131
132 /*
133 * if a socket was bound with I/O completion port
134 * then GetQueuedCompletionStatus() would anyway return its status
135 * despite that WSARecv() was already complete
136 */
137
138 rev->active = 1;
139 return NGX_AGAIN;
140 }
141
142 rev->active = 0;
143
144 return bytes;
145 }
2121 ngx_os_io_t ngx_os_io = {
2222 ngx_wsarecv,
2323 ngx_wsarecv_chain,
24 ngx_udp_wsarecv,
2425 NULL,
2526 ngx_wsasend_chain,
2627 0