Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_linux_aio_read.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 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) {
60  "second aio post for \"%V\"", &file->name);
61  return NGX_AGAIN;
62  }
63 
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 
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 
134  "aio event handler fd:%d %V", aio->fd, &aio->file->name);
135 
136  aio->handler(ev);
137 }