3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
10 #include <ngx_event.h>
14 * FreeBSD file AIO features and quirks:
16 * if an asked data are already in VM cache, then aio_error() returns 0,
17 * and the data are already copied in buffer;
19 * aio_read() preread in VM cache as minimum 16K (probably BKVASIZE);
20 * the first AIO preload may be up to 128K;
22 * aio_read/aio_error() may return EINPROGRESS for just written data;
24 * kqueue EVFILT_AIO filter is level triggered only: an event repeats
25 * until aio_return() will be called;
27 * aio_cancel() cannot cancel file AIO: it returns AIO_NOTCANCELED always.
31 extern int ngx_kqueue
;
34 static ssize_t
ngx_file_aio_result(ngx_file_t
*file
, ngx_event_aio_t
*aio
,
36 static void ngx_file_aio_event_handler(ngx_event_t
*ev
);
40 ngx_file_aio_read(ngx_file_t
*file
, u_char
*buf
, size_t size
, off_t offset
,
48 return ngx_read_file(file
, buf
, size
, offset
);
54 aio
= ngx_pcalloc(pool
, sizeof(ngx_event_aio_t
));
61 aio
->event
.data
= aio
;
63 aio
->event
.log
= file
->log
;
64 #if (NGX_HAVE_AIO_SENDFILE)
65 aio
->last_offset
= -1;
73 ngx_log_error(NGX_LOG_ALERT
, file
->log
, 0,
74 "second aio post for \"%V\"", &file
->name
);
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
);
84 ngx_set_errno(aio
->err
);
90 ngx_log_error(NGX_LOG_CRIT
, file
->log
, ngx_errno
,
91 "aio read \"%s\" failed", file
->name
.data
);
96 ngx_memzero(&aio
->aiocb
, sizeof(struct aiocb
));
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
;
107 ev
->handler
= ngx_file_aio_event_handler
;
109 n
= aio_read(&aio
->aiocb
);
114 if (n
== NGX_EAGAIN
) {
115 return ngx_read_file(file
, buf
, size
, offset
);
118 ngx_log_error(NGX_LOG_CRIT
, file
->log
, n
,
119 "aio_read(\"%V\") failed", &file
->name
);
121 if (n
== NGX_ENOSYS
) {
123 return ngx_read_file(file
, buf
, size
, offset
);
129 ngx_log_debug2(NGX_LOG_DEBUG_CORE
, file
->log
, 0,
130 "aio_read: fd:%d %d", file
->fd
, n
);
136 return ngx_file_aio_result(aio
->file
, aio
, ev
);
141 ngx_file_aio_result(ngx_file_t
*file
, ngx_event_aio_t
*aio
, ngx_event_t
*ev
)
146 n
= aio_error(&aio
->aiocb
);
148 ngx_log_debug2(NGX_LOG_DEBUG_CORE
, file
->log
, 0,
149 "aio_error: fd:%d %d", file
->fd
, n
);
155 ngx_log_error(NGX_LOG_ALERT
, file
->log
, err
,
156 "aio_error(\"%V\") failed", &file
->name
);
160 if (n
== NGX_EINPROGRESS
) {
163 ngx_log_error(NGX_LOG_ALERT
, file
->log
, n
,
164 "aio_read(\"%V\") still in progress",
171 n
= aio_return(&aio
->aiocb
);
178 ngx_log_error(NGX_LOG_CRIT
, file
->log
, err
,
179 "aio_return(\"%V\") failed", &file
->name
);
188 ngx_log_debug2(NGX_LOG_DEBUG_CORE
, file
->log
, 0,
189 "aio_return: fd:%d %d", file
->fd
, n
);
196 ngx_file_aio_event_handler(ngx_event_t
*ev
)
198 ngx_event_aio_t
*aio
;
202 ngx_log_debug2(NGX_LOG_DEBUG_CORE
, ev
->log
, 0,
203 "aio event handler fd:%d %V", aio
->fd
, &aio
->file
->name
);
205 if (ngx_file_aio_result(aio
->file
, aio
, ev
) != NGX_AGAIN
) {