Mercurial > hg > nginx-quic
annotate src/os/unix/ngx_file_aio_read.c @ 5860:c9787372f16d
Limit conn: use complex value in limit_conn_zone (ticket #121).
One intentional side effect of this change is that key is allowed only
in the first position. Previously, it was possible to specify the key
variable at any position, but that was never documented, and is contrary
to nginx configuration practice for positional parameters.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Wed, 24 Sep 2014 21:55:19 +0400 |
parents | 30eff7580d0c |
children | ccad84a174e0 |
rev | line source |
---|---|
3052 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
3052 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_event.h> | |
11 | |
12 | |
13 /* | |
14 * FreeBSD file AIO features and quirks: | |
15 * | |
16 * if an asked data are already in VM cache, then aio_error() returns 0, | |
17 * and the data are already copied in buffer; | |
18 * | |
3065 | 19 * aio_read() preread in VM cache as minimum 16K (probably BKVASIZE); |
20 * the first AIO preload may be up to 128K; | |
3052 | 21 * |
22 * aio_read/aio_error() may return EINPROGRESS for just written data; | |
23 * | |
24 * kqueue EVFILT_AIO filter is level triggered only: an event repeats | |
25 * until aio_return() will be called; | |
26 * | |
4133
59b99f217c6d
Replaced "can not" with "cannot" and "could not" in a bunch of places.
Ruslan Ermilov <ru@nginx.com>
parents:
4076
diff
changeset
|
27 * aio_cancel() cannot cancel file AIO: it returns AIO_NOTCANCELED always. |
3052 | 28 */ |
29 | |
30 | |
31 extern int ngx_kqueue; | |
32 | |
33 | |
34 static ssize_t ngx_file_aio_result(ngx_file_t *file, ngx_event_aio_t *aio, | |
35 ngx_event_t *ev); | |
36 static void ngx_file_aio_event_handler(ngx_event_t *ev); | |
37 | |
38 | |
39 ssize_t | |
40 ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset, | |
41 ngx_pool_t *pool) | |
42 { | |
3294
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3065
diff
changeset
|
43 int n; |
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3065
diff
changeset
|
44 ngx_event_t *ev; |
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3065
diff
changeset
|
45 ngx_event_aio_t *aio; |
3052 | 46 |
3294
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3065
diff
changeset
|
47 if (!ngx_file_aio) { |
3052 | 48 return ngx_read_file(file, buf, size, offset); |
49 } | |
50 | |
51 aio = file->aio; | |
52 | |
53 if (aio == NULL) { | |
54 aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t)); | |
55 if (aio == NULL) { | |
56 return NGX_ERROR; | |
57 } | |
58 | |
59 aio->file = file; | |
60 aio->fd = file->fd; | |
61 aio->event.data = aio; | |
62 aio->event.ready = 1; | |
63 aio->event.log = file->log; | |
3065 | 64 #if (NGX_HAVE_AIO_SENDFILE) |
65 aio->last_offset = -1; | |
66 #endif | |
3052 | 67 file->aio = aio; |
68 } | |
69 | |
70 ev = &aio->event; | |
71 | |
72 if (!ev->ready) { | |
73 ngx_log_error(NGX_LOG_ALERT, file->log, 0, | |
74 "second aio post for \"%V\"", &file->name); | |
75 return NGX_AGAIN; | |
76 } | |
77 | |
78 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, | |
79 "aio complete:%d @%O:%z %V", | |
80 ev->complete, offset, size, &file->name); | |
81 | |
82 if (ev->complete) { | |
83 ev->complete = 0; | |
84 ngx_set_errno(aio->err); | |
85 | |
86 if (aio->err == 0) { | |
87 return aio->nbytes; | |
88 } | |
89 | |
4076
37da005a5808
Bugfix: open_file_cache lost is_directio flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
3294
diff
changeset
|
90 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, |
37da005a5808
Bugfix: open_file_cache lost is_directio flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
3294
diff
changeset
|
91 "aio read \"%s\" failed", file->name.data); |
37da005a5808
Bugfix: open_file_cache lost is_directio flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
3294
diff
changeset
|
92 |
3052 | 93 return NGX_ERROR; |
94 } | |
95 | |
96 ngx_memzero(&aio->aiocb, sizeof(struct aiocb)); | |
97 | |
98 aio->aiocb.aio_fildes = file->fd; | |
99 aio->aiocb.aio_offset = offset; | |
100 aio->aiocb.aio_buf = buf; | |
101 aio->aiocb.aio_nbytes = size; | |
102 #if (NGX_HAVE_KQUEUE) | |
103 aio->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue; | |
104 aio->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT; | |
105 aio->aiocb.aio_sigevent.sigev_value.sigval_ptr = ev; | |
106 #endif | |
107 ev->handler = ngx_file_aio_event_handler; | |
108 | |
109 n = aio_read(&aio->aiocb); | |
110 | |
111 if (n == -1) { | |
112 n = ngx_errno; | |
113 | |
114 if (n == NGX_EAGAIN) { | |
115 return ngx_read_file(file, buf, size, offset); | |
116 } | |
117 | |
118 ngx_log_error(NGX_LOG_CRIT, file->log, n, | |
119 "aio_read(\"%V\") failed", &file->name); | |
120 | |
121 if (n == NGX_ENOSYS) { | |
3294
04cfc09b8b8d
export aio presence knowledge to prevent using "aio sendfile",
Igor Sysoev <igor@sysoev.ru>
parents:
3065
diff
changeset
|
122 ngx_file_aio = 0; |
3052 | 123 return ngx_read_file(file, buf, size, offset); |
124 } | |
125 | |
126 return NGX_ERROR; | |
127 } | |
128 | |
129 ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0, | |
130 "aio_read: fd:%d %d", file->fd, n); | |
131 | |
132 ev->active = 1; | |
133 ev->ready = 0; | |
134 ev->complete = 0; | |
135 | |
136 return ngx_file_aio_result(aio->file, aio, ev); | |
137 } | |
138 | |
139 | |
140 static ssize_t | |
141 ngx_file_aio_result(ngx_file_t *file, ngx_event_aio_t *aio, ngx_event_t *ev) | |
142 { | |
143 int n; | |
144 ngx_err_t err; | |
145 | |
146 n = aio_error(&aio->aiocb); | |
147 | |
148 ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0, | |
149 "aio_error: fd:%d %d", file->fd, n); | |
150 | |
151 if (n == -1) { | |
152 err = ngx_errno; | |
153 aio->err = err; | |
154 | |
155 ngx_log_error(NGX_LOG_ALERT, file->log, err, | |
156 "aio_error(\"%V\") failed", &file->name); | |
157 return NGX_ERROR; | |
158 } | |
159 | |
4415
30eff7580d0c
Fixed AIO error handling on FreeBSD.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
160 if (n == NGX_EINPROGRESS) { |
30eff7580d0c
Fixed AIO error handling on FreeBSD.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
161 if (ev->ready) { |
30eff7580d0c
Fixed AIO error handling on FreeBSD.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
162 ev->ready = 0; |
30eff7580d0c
Fixed AIO error handling on FreeBSD.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
163 ngx_log_error(NGX_LOG_ALERT, file->log, n, |
30eff7580d0c
Fixed AIO error handling on FreeBSD.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
164 "aio_read(\"%V\") still in progress", |
30eff7580d0c
Fixed AIO error handling on FreeBSD.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
165 &file->name); |
3052 | 166 } |
167 | |
4415
30eff7580d0c
Fixed AIO error handling on FreeBSD.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
168 return NGX_AGAIN; |
3052 | 169 } |
170 | |
171 n = aio_return(&aio->aiocb); | |
172 | |
173 if (n == -1) { | |
174 err = ngx_errno; | |
175 aio->err = err; | |
4415
30eff7580d0c
Fixed AIO error handling on FreeBSD.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
176 ev->ready = 1; |
3052 | 177 |
4415
30eff7580d0c
Fixed AIO error handling on FreeBSD.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
178 ngx_log_error(NGX_LOG_CRIT, file->log, err, |
3052 | 179 "aio_return(\"%V\") failed", &file->name); |
180 return NGX_ERROR; | |
181 } | |
182 | |
183 aio->err = 0; | |
184 aio->nbytes = n; | |
185 ev->ready = 1; | |
186 ev->active = 0; | |
187 | |
188 ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0, | |
189 "aio_return: fd:%d %d", file->fd, n); | |
190 | |
191 return n; | |
192 } | |
193 | |
194 | |
195 static void | |
196 ngx_file_aio_event_handler(ngx_event_t *ev) | |
197 { | |
198 ngx_event_aio_t *aio; | |
199 | |
200 aio = ev->data; | |
201 | |
202 ngx_log_debug2(NGX_LOG_DEBUG_CORE, ev->log, 0, | |
203 "aio event handler fd:%d %V", aio->fd, &aio->file->name); | |
204 | |
205 if (ngx_file_aio_result(aio->file, aio, ev) != NGX_AGAIN) { | |
206 aio->handler(ev); | |
207 } | |
208 } |