… | |
… | |
125 | /*int inuse;*/ |
125 | /*int inuse;*/ |
126 | } *ANIOCBP; |
126 | } *ANIOCBP; |
127 | |
127 | |
128 | inline_size |
128 | inline_size |
129 | void |
129 | void |
130 | linuxaio_array_needsize_iocbp (ANIOCBP *base, int count) |
130 | linuxaio_array_needsize_iocbp (ANIOCBP *base, int offset, int count) |
131 | { |
131 | { |
132 | /* TODO: quite the overhead to allocate every iocb separately, maybe use our own alocator? */ |
|
|
133 | while (count--) |
132 | while (count--) |
134 | { |
133 | { |
|
|
134 | /* TODO: quite the overhead to allocate every iocb separately, maybe use our own alocator? */ |
135 | *base = (ANIOCBP)ev_malloc (sizeof (**base)); |
135 | ANIOCBP iocb = (ANIOCBP)ev_malloc (sizeof (*iocb)); |
136 | /* TODO: full zero initialize required? */ |
136 | |
|
|
137 | /* full zero initialise is probably not required at the moment, but |
|
|
138 | * this is not well documented, so we better do it. |
|
|
139 | */ |
137 | memset (*base, 0, sizeof (**base)); |
140 | memset (iocb, 0, sizeof (*iocb)); |
138 | /* would be nice to initialize fd/data as well, but array_needsize API doesn't support that */ |
141 | |
139 | (*base)->io.aio_lio_opcode = IOCB_CMD_POLL; |
142 | iocb->io.aio_lio_opcode = IOCB_CMD_POLL; |
140 | ++base; |
143 | iocb->io.aio_data = offset; |
|
|
144 | iocb->io.aio_fildes = offset; |
|
|
145 | |
|
|
146 | base [offset++] = iocb; |
141 | } |
147 | } |
142 | } |
148 | } |
143 | |
149 | |
144 | ecb_cold |
150 | ecb_cold |
145 | static void |
151 | static void |
… | |
… | |
153 | |
159 | |
154 | static void |
160 | static void |
155 | linuxaio_modify (EV_P_ int fd, int oev, int nev) |
161 | linuxaio_modify (EV_P_ int fd, int oev, int nev) |
156 | { |
162 | { |
157 | array_needsize (ANIOCBP, linuxaio_iocbps, linuxaio_iocbpmax, fd + 1, linuxaio_array_needsize_iocbp); |
163 | array_needsize (ANIOCBP, linuxaio_iocbps, linuxaio_iocbpmax, fd + 1, linuxaio_array_needsize_iocbp); |
158 | struct aniocb *iocb = linuxaio_iocbps [fd]; |
164 | ANIOCBP iocb = linuxaio_iocbps [fd]; |
159 | |
165 | |
160 | #if EPOLL_FALLBACK |
166 | #if EPOLL_FALLBACK |
161 | if (iocb->io.aio_reqprio < 0) |
167 | if (iocb->io.aio_reqprio < 0) |
162 | { |
168 | { |
163 | epoll_ctl (backend_fd, EPOLL_CTL_DEL, fd, 0); |
169 | epoll_ctl (backend_fd, EPOLL_CTL_DEL, fd, 0); |
… | |
… | |
168 | if (iocb->io.aio_buf) |
174 | if (iocb->io.aio_buf) |
169 | evsys_io_cancel (linuxaio_ctx, &iocb->io, (struct io_event *)0); /* always returns an error relevant kernels */ |
175 | evsys_io_cancel (linuxaio_ctx, &iocb->io, (struct io_event *)0); /* always returns an error relevant kernels */ |
170 | |
176 | |
171 | if (nev) |
177 | if (nev) |
172 | { |
178 | { |
173 | iocb->io.aio_data = fd; |
|
|
174 | iocb->io.aio_fildes = fd; |
|
|
175 | iocb->io.aio_buf = |
179 | iocb->io.aio_buf = |
176 | (nev & EV_READ ? POLLIN : 0) |
180 | (nev & EV_READ ? POLLIN : 0) |
177 | | (nev & EV_WRITE ? POLLOUT : 0); |
181 | | (nev & EV_WRITE ? POLLOUT : 0); |
178 | |
182 | |
179 | /* queue iocb up for io_submit */ |
183 | /* queue iocb up for io_submit */ |
180 | /* this assumes we only ever get one call per fd per loop iteration */ |
184 | /* this assumes we only ever get one call per fd per loop iteration */ |
… | |
… | |
250 | linuxaio_iocbps [fd]->io.aio_buf = 0; |
254 | linuxaio_iocbps [fd]->io.aio_buf = 0; |
251 | anfds [fd].events = 0; |
255 | anfds [fd].events = 0; |
252 | fd_change (EV_A_ fd, 0); |
256 | fd_change (EV_A_ fd, 0); |
253 | |
257 | |
254 | /* feed events, we do not expect or handle POLLNVAL */ |
258 | /* feed events, we do not expect or handle POLLNVAL */ |
255 | if (expect_false (res & POLLNVAL)) |
|
|
256 | fd_kill (EV_A_ fd); |
|
|
257 | else |
|
|
258 | fd_event ( |
259 | fd_event ( |
259 | EV_A_ |
260 | EV_A_ |
260 | fd, |
261 | fd, |
261 | (res & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0) |
262 | (res & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0) |
262 | | (res & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0) |
263 | | (res & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0) |
263 | ); |
264 | ); |
264 | |
265 | |
265 | --nr; |
266 | --nr; |
266 | ++ev; |
267 | ++ev; |
267 | } |
268 | } |
268 | } |
269 | } |
… | |
… | |
399 | * See https://lore.kernel.org/patchwork/patch/1047453/ to see |
400 | * See https://lore.kernel.org/patchwork/patch/1047453/ to see |
400 | * discussion about such a case (ttys) where polling for POLLIN |
401 | * discussion about such a case (ttys) where polling for POLLIN |
401 | * fails but POLLIN|POLLOUT works. |
402 | * fails but POLLIN|POLLOUT works. |
402 | */ |
403 | */ |
403 | struct iocb *iocb = linuxaio_submits [submitted]; |
404 | struct iocb *iocb = linuxaio_submits [submitted]; |
|
|
405 | |
|
|
406 | linuxaio_rearm_epoll (EV_A_ linuxaio_submits [submitted], EPOLL_CTL_ADD); |
|
|
407 | iocb->aio_reqprio = -1; /* mark iocb as epoll */ |
|
|
408 | |
404 | res = 1; /* skip this iocb */ |
409 | res = 1; /* skip this iocb */ |
405 | |
|
|
406 | linuxaio_rearm_epoll (EV_A_ iocb, EPOLL_CTL_ADD); |
|
|
407 | iocb->aio_reqprio = -1; /* mark iocb as epoll */ |
|
|
408 | } |
410 | } |
409 | #endif |
411 | #endif |
|
|
412 | else if (errno == EBADF) |
|
|
413 | { |
|
|
414 | fd_kill (EV_A_ linuxaio_submits [submitted]->aio_fildes); |
|
|
415 | |
|
|
416 | res = 1; /* skip this iocb */ |
|
|
417 | } |
410 | else |
418 | else |
411 | ev_syserr ("(libev) linuxaio io_submit"); |
419 | ev_syserr ("(libev) linuxaio io_submit"); |
412 | |
420 | |
413 | submitted += res; |
421 | submitted += res; |
414 | } |
422 | } |
… | |
… | |
473 | { |
481 | { |
474 | #if EPOLL_FALLBACK |
482 | #if EPOLL_FALLBACK |
475 | close (backend_fd); |
483 | close (backend_fd); |
476 | #endif |
484 | #endif |
477 | linuxaio_free_iocbp (EV_A); |
485 | linuxaio_free_iocbp (EV_A); |
478 | ev_io_destroy (linuxaio_ctx); |
486 | evsys_io_destroy (linuxaio_ctx); |
479 | } |
487 | } |
480 | |
488 | |
481 | inline_size |
489 | inline_size |
482 | void |
490 | void |
483 | linuxaio_fork (EV_P) |
491 | linuxaio_fork (EV_P) |