summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsidor Kouvelas <kouvelas@arista.com>2018-10-30 08:50:08 -0700
committerAzat Khuzhin <a3at.mail@gmail.com>2018-10-31 01:21:07 +0300
commitb77d3e787b5522380c65838d3baa22e661eff0db (patch)
treed2167621a7b416752a7243bd119ff43b3f125287
parent77c0e510581b88242d7d7bcff4954cedc5613554 (diff)
downloadlibevent-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.c9
-rw-r--r--evmap.c3
2 files changed, 8 insertions, 4 deletions
diff --git a/epoll.c b/epoll.c
index bf730b23..a0df0d21 100644
--- a/epoll.c
+++ b/epoll.c
@@ -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);
}
diff --git a/evmap.c b/evmap.c
index 3f76dd0a..1eb70696 100644
--- a/evmap.c
+++ b/evmap.c
@@ -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;