Redundant epoll_ctl with ev_io watcher

Nick Zavaritsky mejedi at gmail.com
Thu Nov 5 18:57:43 CET 2015


Hi, Marc!

Please kindly provide some advice.

Tarantool.org is observing redundant epoll_ctl(EPOLL_CTL_ADD) when using ev_io watchers.

Here is the (edited) strace fragment:

read(7, 0x7f8a23008030, 16336)          = -1 EAGAIN (Resource temporarily unavailable)
epoll_ctl(4, EPOLL_CTL_ADD, 7, {EPOLLIN, {u32=7, u64=4294967303}}) = 0
epoll_wait(4, {{EPOLLIN, {u32=7, u64=4294967303}}}, 64, 59743) = 1
read(7, "1\n", 16336)                   = 2
read(7, 0x7f8a23008032, 16334)          = -1 EAGAIN (Resource temporarily unavailable)
epoll_ctl(4, EPOLL_CTL_ADD, 7, {EPOLLIN, {u32=7, u64=8589934599}}) = -1 EEXIST (File exists)


Presumably the problem is due to the code doing ev_io_init before starting the watcher again (borrowing example from the manual):

static void
stdin_readable_cb (struct ev_loop *loop, ev_io *w, int revents)
{
     ev_io_stop (loop, w);
     .. consume input ..
     ev_io_init (w, stdin_readable_cb, w->fd, EV_READ); /* < A culprit? */
     ev_io_start(loop, w);
}

...
struct ev_loop *loop = ev_default_init (0);
ev_io stdin_readable;
ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ);
ev_io_start (loop, &stdin_readable);
ev_run (loop, 0);


As far as I understand ’the special problem of disappearing file descriptors’, by doing ev_io_init we trigger full re-initialization, just in case the fd was reused and is referencing another object now.

Unfortunately we can’t get rid of that ev_io_init. In fact we are using C coroutines and we have a function like wait_fd(int). When called, wait_fd initializes a brand new ev_io watcher, starts the watcher and finally switches to another coroutine. Eventually the ev_io handler transfers control back to the original coroutine, resuming wait_fd. Once wait_fd completes, the watcher is no more.


How wrong would it be to bypass ev_io_set when we know for sure that the descriptor didn’t get reused in the meantime?

Can we change watcher flags directly provided that it is inactive?

Thanks,
Nick


More information about the libev mailing list