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
_______________________________________________
libev mailing list
[email protected]
http://lists.schmorp.de/mailman/listinfo/libev