*** empty log message ***

master
Marc Alexander Lehmann 2019-07-09 00:04:35 +00:00
parent 5c88c9c8d4
commit de01eb22da
3 changed files with 25 additions and 12 deletions

View File

@ -1,14 +1,16 @@
Revision history for libev, a high-performance and full-featured event loop.
TODO: revisit 59.x timer in the light of mdoenr powersaving
TODO: revisit 59.x timer in the light of modern powersaving
TODO: maybe use timerfd to detect time jumps on linux
- linuxaio backend resulted in random memory corruption
when loop is forked.
- linuxaio backend might have tried to cancel an iocb
multiple times (was unable to trigger this).
- linuxaio backend now employs a generation counter to
avoid handlign spurious events from cancelled requests.
- io_cancel can return EINTR, deal with it. also, assume
io_asubmit also retursn EINTR.
- fix some othe rminor bugs in linuxaio backend.
io_submit also returns EINTR.
- fix some other minor bugs in linuxaio backend.
- cleanup: replace expect_true/false and noinline by their
libecb counterparts.
- move syscall infrastructure from ev_linuxaio.c to ev.c.

View File

@ -381,17 +381,17 @@ iouring_modify (EV_P_ int fd, int oev, int nev)
sqe->fd = fd;
sqe->user_data = -1;
iouring_sqe_submit (EV_A_ sqe);
}
/* increment generation counter to avoid handling old events */
++anfds [fd].egen;
/* increment generation counter to avoid handling old events */
++anfds [fd].egen;
}
if (nev)
{
struct io_uring_sqe *sqe = iouring_sqe_get (EV_A);
sqe->opcode = IORING_OP_POLL_ADD;
sqe->fd = fd;
sqe->user_data = (uint32_t)fd | ((__u64)anfds [fd].egen << 32);
sqe->user_data = (uint32_t)fd | ((__u64)(uint32_t)anfds [fd].egen << 32);
sqe->poll_events =
(nev & EV_READ ? POLLIN : 0)
| (nev & EV_WRITE ? POLLOUT : 0);
@ -444,7 +444,7 @@ iouring_process_cqe (EV_P_ struct io_uring_cqe *cqe)
/* ignore event if generation doesn't match */
/* this should actually be very rare */
if (ecb_expect_false ((uint32_t)anfds [fd].egen != gen))
if (ecb_expect_false (gen != (uint32_t)anfds [fd].egen))
return;
if (ecb_expect_false (res < 0))

View File

@ -214,7 +214,6 @@ linuxaio_array_needsize_iocbp (ANIOCBP *base, int offset, int count)
memset (iocb, 0, sizeof (*iocb));
iocb->io.aio_lio_opcode = IOCB_CMD_POLL;
iocb->io.aio_data = offset;
iocb->io.aio_fildes = offset;
base [offset++] = iocb;
@ -236,18 +235,20 @@ linuxaio_modify (EV_P_ int fd, int oev, int nev)
{
array_needsize (ANIOCBP, linuxaio_iocbps, linuxaio_iocbpmax, fd + 1, linuxaio_array_needsize_iocbp);
ANIOCBP iocb = linuxaio_iocbps [fd];
ANFD *anfd = &anfds [fd];
if (ecb_expect_false (iocb->io.aio_reqprio < 0))
{
/* we handed this fd over to epoll, so undo this first */
/* we do it manually because the optimisations on epoll_modify won't do us any good */
epoll_ctl (backend_fd, EPOLL_CTL_DEL, fd, 0);
anfds [fd].emask = 0;
anfd->emask = 0;
iocb->io.aio_reqprio = 0;
}
else if (ecb_expect_false (iocb->io.aio_buf))
{
/* iocb active, so cancel it first before resubmit */
/* this assumes we only ever get one call per fd per loop iteration */
for (;;)
{
/* on all relevant kernels, io_cancel fails with EINPROGRESS on "success" */
@ -264,6 +265,9 @@ linuxaio_modify (EV_P_ int fd, int oev, int nev)
break;
}
}
/* increment generation counter to avoid handling old events */
++anfd->egen;
}
iocb->io.aio_buf =
@ -272,6 +276,8 @@ linuxaio_modify (EV_P_ int fd, int oev, int nev)
if (nev)
{
iocb->io.aio_data = (uint32_t)fd | ((__u64)(uint32_t)anfd->egen << 32);
/* queue iocb up for io_submit */
/* this assumes we only ever get one call per fd per loop iteration */
++linuxaio_submitcnt;
@ -300,11 +306,16 @@ linuxaio_parse_events (EV_P_ struct io_event *ev, int nr)
{
while (nr)
{
int fd = ev->data;
int res = ev->res;
int fd = ev->data & 0xffffffff;
uint32_t gen = ev->data >> 32;
int res = ev->res;
assert (("libev: iocb fd must be in-bounds", fd >= 0 && fd < anfdmax));
/* ignore event if generation doesn't match */
if (ecb_expect_false (gen != (uint32_t)anfds [fd].egen))
continue;
/* feed events, we do not expect or handle POLLNVAL */
fd_event (
EV_A_