comparison src/os/unix/ngx_recv.c @ 0:f0b350454894 NGINX_0_1_0

nginx 0.1.0 *) The first public version.
author Igor Sysoev <http://sysoev.ru>
date Mon, 04 Oct 2004 00:00:00 +0400
parents
children 4b2dafa26fe2
comparison
equal deleted inserted replaced
-1:000000000000 0:f0b350454894
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 #if (HAVE_KQUEUE)
13
14 ssize_t ngx_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 if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
23 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
24 "recv: eof:%d, avail:%d, err:%d",
25 rev->pending_eof, rev->available, rev->kq_errno);
26
27 if (rev->available == 0) {
28 if (rev->pending_eof) {
29 rev->ready = 0;
30 rev->eof = 1;
31
32 ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
33 "kevent() reported about an closed connection");
34
35 if (rev->kq_errno) {
36 rev->error = 1;
37 ngx_set_socket_errno(rev->kq_errno);
38
39 if (rev->kq_errno == NGX_ECONNRESET
40 && c->log_error == NGX_ERROR_IGNORE_ECONNRESET)
41 {
42 return 0;
43 }
44
45 return NGX_ERROR;
46 }
47
48 return 0;
49
50 } else {
51 return NGX_AGAIN;
52 }
53 }
54 }
55
56 do {
57 n = recv(c->fd, buf, size, 0);
58
59 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
60 "recv: fd:%d %d of %d", c->fd, n, size);
61
62 if (n >= 0) {
63 if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
64 rev->available -= n;
65
66 /*
67 * rev->available can be negative here because some additional
68 * bytes can be received between kevent() and recv()
69 */
70
71 if (rev->available <= 0) {
72 if (!rev->pending_eof) {
73 rev->ready = 0;
74 }
75
76 if (rev->available < 0) {
77 rev->available = 0;
78 }
79 }
80
81 return n;
82 }
83
84 if ((size_t) n < size) {
85 rev->ready = 0;
86 }
87
88 if (n == 0) {
89 rev->eof = 1;
90 }
91
92 return n;
93 }
94
95 err = ngx_socket_errno;
96
97 if (err == NGX_EAGAIN || err == NGX_EINTR) {
98 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
99 "recv() not ready");
100 n = NGX_AGAIN;
101
102 } else {
103 n = ngx_connection_error(c, err, "recv() failed");
104 break;
105 }
106
107 } while (err == NGX_EINTR);
108
109 rev->ready = 0;
110
111 if (n == NGX_ERROR){
112 rev->error = 1;
113 }
114
115 return n;
116 }
117
118 #else /* ! NAVE_KQUEUE */
119
120 ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
121 {
122 ssize_t n;
123 ngx_err_t err;
124 ngx_event_t *rev;
125
126 rev = c->read;
127
128 do {
129 n = recv(c->fd, buf, size, 0);
130
131 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
132 "recv: fd:%d %d of %d", c->fd, n, size);
133
134 if (n == 0) {
135 rev->ready = 0;
136 rev->eof = 1;
137 return n;
138
139 } else if (n > 0) {
140
141 if ((size_t) n < size
142 && !(ngx_event_flags & NGX_HAVE_GREEDY_EVENT))
143 {
144 rev->ready = 0;
145 }
146
147 return n;
148 }
149
150 err = ngx_socket_errno;
151
152 if (err == NGX_EAGAIN || err == NGX_EINTR) {
153 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
154 "recv() not ready");
155 n = NGX_AGAIN;
156
157 } else {
158 n = ngx_connection_error(c, err, "recv() failed");
159 break;
160 }
161
162 } while (err == NGX_EINTR);
163
164 rev->ready = 0;
165
166 if (n == NGX_ERROR){
167 rev->error = 1;
168 }
169
170 return n;
171 }
172
173 #endif /* NAVE_KQUEUE */