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