diff --git a/Changes b/Changes index fbacc83..bbc8e8b 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,8 @@ Revision history for libev, a high-performance and full-featured event loop. TODO: revisit 59.x timer in the light of mdoenr powersaving + - linuxaio backend might have tried to cancel an iocb + multiple times (was unable to trigger this). - io_cancel can return EINTR, deal with it. also, assume io_asubmit also retursn EINTR. diff --git a/ev_linuxaio.c b/ev_linuxaio.c index aed198b..62a220b 100644 --- a/ev_linuxaio.c +++ b/ev_linuxaio.c @@ -288,7 +288,7 @@ 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]; - if (iocb->io.aio_reqprio < 0) + if (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 */ @@ -297,8 +297,9 @@ linuxaio_modify (EV_P_ int fd, int oev, int nev) iocb->io.aio_reqprio = 0; } - if (iocb->io.aio_buf) + if (expect_false (iocb->io.aio_buf)) { + /* iocb active, so cancel it first before resubmit */ for (;;) { /* on all relevant kernels, io_cancel fails with EINPROGRESS on "success" */ @@ -313,12 +314,12 @@ linuxaio_modify (EV_P_ int fd, int oev, int nev) } } + iocb->io.aio_buf = + (nev & EV_READ ? POLLIN : 0) + | (nev & EV_WRITE ? POLLOUT : 0); + if (nev) { - iocb->io.aio_buf = - (nev & EV_READ ? POLLIN : 0) - | (nev & EV_WRITE ? POLLOUT : 0); - /* queue iocb up for io_submit */ /* this assumes we only ever get one call per fd per loop iteration */ ++linuxaio_submitcnt;