diff options
author | Isidor Kouvelas <kouvelas@arista.com> | 2018-10-30 08:50:08 -0700 |
---|---|---|
committer | Azat Khuzhin <a3at.mail@gmail.com> | 2018-10-31 01:21:07 +0300 |
commit | b77d3e787b5522380c65838d3baa22e661eff0db (patch) | |
tree | d2167621a7b416752a7243bd119ff43b3f125287 | |
parent | 77c0e510581b88242d7d7bcff4954cedc5613554 (diff) | |
download | libevent-b77d3e787b5522380c65838d3baa22e661eff0db.tar.gz |
Epoll ET setting lost with multiple events for same fd
After two or more events have been registered for the same file
descriptor using EV_ET, if one of the events is deleted, then the
epoll_ctl() call issued by libevent drops the EPOLLET flag resulting in
level triggered notifications.
[ azat: use existing "et" in the evmap_io_del_() ]
-rw-r--r-- | epoll.c | 9 | ||||
-rw-r--r-- | evmap.c | 3 |
2 files changed, 8 insertions, 4 deletions
@@ -401,11 +401,14 @@ epoll_nochangelist_del(struct event_base *base, evutil_socket_t fd, ch.old_events = old; ch.read_change = ch.write_change = ch.close_change = 0; if (events & EV_WRITE) - ch.write_change = EV_CHANGE_DEL; + ch.write_change = EV_CHANGE_DEL | + (events & EV_ET); if (events & EV_READ) - ch.read_change = EV_CHANGE_DEL; + ch.read_change = EV_CHANGE_DEL | + (events & EV_ET); if (events & EV_CLOSED) - ch.close_change = EV_CHANGE_DEL; + ch.close_change = EV_CHANGE_DEL | + (events & EV_ET); return epoll_apply_one_change(base, base->evbase, &ch); } @@ -393,7 +393,8 @@ evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev) if (res) { void *extra = ((char*)ctx) + sizeof(struct evmap_io); - if (evsel->del(base, ev->ev_fd, old, res, extra) == -1) { + if (evsel->del(base, ev->ev_fd, + old, (ev->ev_events & EV_ET) | res, extra) == -1) { retval = -1; } else { retval = 1; |