Groonga 3.0.9 Source Code Document
Main Page
Related Pages
Namespaces
Data Structures
Files
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Pages
groonga
vendor
nginx-1.4.2
src
os
unix
ngx_readv_chain.c
Go to the documentation of this file.
1
2
/*
3
* Copyright (C) Igor Sysoev
4
* Copyright (C) Nginx, Inc.
5
*/
6
7
8
#include <
ngx_config.h
>
9
#include <
ngx_core.h
>
10
#include <
ngx_event.h
>
11
12
13
#define NGX_IOVS 16
14
15
16
#if (NGX_HAVE_KQUEUE)
17
18
ssize_t
19
ngx_readv_chain
(
ngx_connection_t
*c,
ngx_chain_t
*chain)
20
{
21
u_char *prev;
22
ssize_t n, size;
23
ngx_err_t
err;
24
ngx_array_t
vec;
25
ngx_event_t
*rev;
26
struct
iovec *iov, iovs[
NGX_IOVS
];
27
28
rev = c->
read
;
29
30
if
(
ngx_event_flags
&
NGX_USE_KQUEUE_EVENT
) {
31
ngx_log_debug3
(
NGX_LOG_DEBUG_EVENT
, c->
log
, 0,
32
"readv: eof:%d, avail:%d, err:%d"
,
33
rev->
pending_eof
, rev->
available
, rev->kq_errno);
34
35
if
(rev->
available
== 0) {
36
if
(rev->
pending_eof
) {
37
rev->
ready
= 0;
38
rev->
eof
= 1;
39
40
ngx_log_error
(
NGX_LOG_INFO
, c->
log
, rev->kq_errno,
41
"kevent() reported about an closed connection"
);
42
43
if
(rev->kq_errno) {
44
rev->
error
= 1;
45
ngx_set_socket_errno
(rev->kq_errno);
46
return
NGX_ERROR
;
47
}
48
49
return
0;
50
51
}
else
{
52
return
NGX_AGAIN
;
53
}
54
}
55
}
56
57
prev = NULL;
58
iov = NULL;
59
size = 0;
60
61
vec.
elts
= iovs;
62
vec.
nelts
= 0;
63
vec.
size
=
sizeof
(
struct
iovec);
64
vec.
nalloc
=
NGX_IOVS
;
65
vec.
pool
= c->
pool
;
66
67
/* coalesce the neighbouring bufs */
68
69
while
(chain) {
70
if
(prev == chain->
buf
->
last
) {
71
iov->iov_len += chain->
buf
->
end
- chain->
buf
->
last
;
72
73
}
else
{
74
if
(vec.
nelts
>=
IOV_MAX
) {
75
break
;
76
}
77
78
iov =
ngx_array_push
(&vec);
79
if
(iov == NULL) {
80
return
NGX_ERROR
;
81
}
82
83
iov->iov_base = (
void
*) chain->
buf
->
last
;
84
iov->iov_len = chain->
buf
->
end
- chain->
buf
->
last
;
85
}
86
87
size += chain->
buf
->
end
- chain->
buf
->
last
;
88
prev = chain->
buf
->
end
;
89
chain = chain->
next
;
90
}
91
92
ngx_log_debug2
(
NGX_LOG_DEBUG_EVENT
, c->
log
, 0,
93
"readv: %d, last:%d"
, vec.
nelts
, iov->iov_len);
94
95
rev = c->
read
;
96
97
do
{
98
n = readv(c->
fd
, (
struct
iovec *) vec.
elts
, vec.
nelts
);
99
100
if
(n >= 0) {
101
if
(
ngx_event_flags
& NGX_USE_KQUEUE_EVENT) {
102
rev->
available
-= n;
103
104
/*
105
* rev->available may be negative here because some additional
106
* bytes may be received between kevent() and recv()
107
*/
108
109
if
(rev->
available
<= 0) {
110
if
(!rev->
pending_eof
) {
111
rev->
ready
= 0;
112
}
113
114
if
(rev->
available
< 0) {
115
rev->
available
= 0;
116
}
117
}
118
119
if
(n == 0) {
120
121
/*
122
* on FreeBSD recv() may return 0 on closed socket
123
* even if kqueue reported about available data
124
*/
125
126
#if 0
127
ngx_log_error
(
NGX_LOG_ALERT
, c->
log
, 0,
128
"readv() returned 0 while kevent() reported "
129
"%d available bytes"
, rev->
available
);
130
#endif
131
132
rev->
eof
= 1;
133
rev->
available
= 0;
134
}
135
136
return
n;
137
}
138
139
if
(n < size) {
140
rev->
ready
= 0;
141
}
142
143
if
(n == 0) {
144
rev->
eof
= 1;
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
"readv() not ready"
);
155
n =
NGX_AGAIN
;
156
157
}
else
{
158
n =
ngx_connection_error
(c, err,
"readv() failed"
);
159
break
;
160
}
161
162
}
while
(err ==
NGX_EINTR
);
163
164
rev->
ready
= 0;
165
166
if
(n ==
NGX_ERROR
) {
167
c->
read
->
error
= 1;
168
}
169
170
return
n;
171
}
172
173
#else
/* ! NGX_HAVE_KQUEUE */
174
175
ssize_t
176
ngx_readv_chain
(
ngx_connection_t
*c,
ngx_chain_t
*chain)
177
{
178
u_char *prev;
179
ssize_t n, size;
180
ngx_err_t
err;
181
ngx_array_t
vec;
182
ngx_event_t
*rev;
183
struct
iovec *iov, iovs[
NGX_IOVS
];
184
185
prev = NULL;
186
iov = NULL;
187
size = 0;
188
189
vec.
elts
= iovs;
190
vec.
nelts
= 0;
191
vec.
size
=
sizeof
(
struct
iovec);
192
vec.
nalloc
=
NGX_IOVS
;
193
vec.
pool
= c->
pool
;
194
195
/* coalesce the neighbouring bufs */
196
197
while
(chain) {
198
if
(prev == chain->
buf
->
last
) {
199
iov->iov_len += chain->
buf
->
end
- chain->
buf
->
last
;
200
201
}
else
{
202
if
(vec.
nelts
>=
IOV_MAX
) {
203
break
;
204
}
205
206
iov =
ngx_array_push
(&vec);
207
if
(iov == NULL) {
208
return
NGX_ERROR
;
209
}
210
211
iov->iov_base = (
void
*) chain->
buf
->
last
;
212
iov->iov_len = chain->
buf
->
end
- chain->
buf
->
last
;
213
}
214
215
size += chain->
buf
->
end
- chain->
buf
->
last
;
216
prev = chain->
buf
->
end
;
217
chain = chain->
next
;
218
}
219
220
ngx_log_debug2
(
NGX_LOG_DEBUG_EVENT
, c->
log
, 0,
221
"readv: %d:%d"
, vec.
nelts
, iov->iov_len);
222
223
rev = c->
read
;
224
225
do
{
226
n = readv(c->
fd
, (
struct
iovec *) vec.
elts
, vec.
nelts
);
227
228
if
(n == 0) {
229
rev->
ready
= 0;
230
rev->
eof
= 1;
231
232
return
n;
233
234
}
else
if
(n > 0) {
235
236
if
(n < size && !(
ngx_event_flags
&
NGX_USE_GREEDY_EVENT
)) {
237
rev->
ready
= 0;
238
}
239
240
return
n;
241
}
242
243
err =
ngx_socket_errno
;
244
245
if
(err ==
NGX_EAGAIN
|| err ==
NGX_EINTR
) {
246
ngx_log_debug0
(
NGX_LOG_DEBUG_EVENT
, c->
log
, err,
247
"readv() not ready"
);
248
n =
NGX_AGAIN
;
249
250
}
else
{
251
n =
ngx_connection_error
(c, err,
"readv() failed"
);
252
break
;
253
}
254
255
}
while
(err ==
NGX_EINTR
);
256
257
rev->
ready
= 0;
258
259
if
(n ==
NGX_ERROR
) {
260
c->
read
->
error
= 1;
261
}
262
263
return
n;
264
}
265
266
#endif
/* NGX_HAVE_KQUEUE */
Generated on Sun Nov 10 2013 09:49:09 for Groonga 3.0.9 Source Code Document by
1.8.1.2