Annotation of embedaddon/nginx/src/os/unix/ngx_linux_aio_read.c, revision 1.1.1.1
1.1 misho 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: extern int ngx_eventfd;
14: extern aio_context_t ngx_aio_ctx;
15:
16:
17: static void ngx_file_aio_event_handler(ngx_event_t *ev);
18:
19:
20: static int
21: io_submit(aio_context_t ctx, long n, struct iocb **paiocb)
22: {
23: return syscall(SYS_io_submit, ctx, n, paiocb);
24: }
25:
26:
27: ssize_t
28: ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
29: ngx_pool_t *pool)
30: {
31: ngx_err_t err;
32: struct iocb *piocb[1];
33: ngx_event_t *ev;
34: ngx_event_aio_t *aio;
35:
36: if (!ngx_file_aio) {
37: return ngx_read_file(file, buf, size, offset);
38: }
39:
40: aio = file->aio;
41:
42: if (aio == NULL) {
43: aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t));
44: if (aio == NULL) {
45: return NGX_ERROR;
46: }
47:
48: aio->file = file;
49: aio->fd = file->fd;
50: aio->event.data = aio;
51: aio->event.ready = 1;
52: aio->event.log = file->log;
53: file->aio = aio;
54: }
55:
56: ev = &aio->event;
57:
58: if (!ev->ready) {
59: ngx_log_error(NGX_LOG_ALERT, file->log, 0,
60: "second aio post for \"%V\"", &file->name);
61: return NGX_AGAIN;
62: }
63:
64: ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
65: "aio complete:%d @%O:%z %V",
66: ev->complete, offset, size, &file->name);
67:
68: if (ev->complete) {
69: ev->active = 0;
70: ev->complete = 0;
71:
72: if (aio->res >= 0) {
73: ngx_set_errno(0);
74: return aio->res;
75: }
76:
77: ngx_set_errno(-aio->res);
78:
79: ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
80: "aio read \"%s\" failed", file->name.data);
81:
82: return NGX_ERROR;
83: }
84:
85: ngx_memzero(&aio->aiocb, sizeof(struct iocb));
86:
87: aio->aiocb.aio_data = (uint64_t) (uintptr_t) ev;
88: aio->aiocb.aio_lio_opcode = IOCB_CMD_PREAD;
89: aio->aiocb.aio_fildes = file->fd;
90: aio->aiocb.aio_buf = (uint64_t) (uintptr_t) buf;
91: aio->aiocb.aio_nbytes = size;
92: aio->aiocb.aio_offset = offset;
93: aio->aiocb.aio_flags = IOCB_FLAG_RESFD;
94: aio->aiocb.aio_resfd = ngx_eventfd;
95:
96: ev->handler = ngx_file_aio_event_handler;
97:
98: piocb[0] = &aio->aiocb;
99:
100: if (io_submit(ngx_aio_ctx, 1, piocb) == 1) {
101: ev->active = 1;
102: ev->ready = 0;
103: ev->complete = 0;
104:
105: return NGX_AGAIN;
106: }
107:
108: err = ngx_errno;
109:
110: if (err == NGX_EAGAIN) {
111: return ngx_read_file(file, buf, size, offset);
112: }
113:
114: ngx_log_error(NGX_LOG_CRIT, file->log, err,
115: "io_submit(\"%V\") failed", &file->name);
116:
117: if (err == NGX_ENOSYS) {
118: ngx_file_aio = 0;
119: return ngx_read_file(file, buf, size, offset);
120: }
121:
122: return NGX_ERROR;
123: }
124:
125:
126: static void
127: ngx_file_aio_event_handler(ngx_event_t *ev)
128: {
129: ngx_event_aio_t *aio;
130:
131: aio = ev->data;
132:
133: ngx_log_debug2(NGX_LOG_DEBUG_CORE, ev->log, 0,
134: "aio event handler fd:%d %V", aio->fd, &aio->file->name);
135:
136: aio->handler(ev);
137: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>