From 4d3adaa557d24a912bf94bad26a83f7bb01253fd Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 17 Apr 2024 14:45:46 +0200 Subject: [PATCH] event/SocketEvent: erase IMPLICIT_FLAGS in Cancel{Read,Write}() Without this, calling CancelRead() after ScheduleRead() would leave the HANGUP scheduled, and the caller could receive HANGUP events over and over which are never properly handled, leading to a busy loop. The semantics of this API are hard to get right, because the IMPLICIT_FLAGS (a property of epoll) are somewhat weird. But it seems that this change repairs a side effect of the SocketEvent interface that seemed counterintuitive. --- src/event/SocketEvent.hxx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/event/SocketEvent.hxx b/src/event/SocketEvent.hxx index 1f5684103..a6121a453 100644 --- a/src/event/SocketEvent.hxx +++ b/src/event/SocketEvent.hxx @@ -137,11 +137,15 @@ public: } void CancelRead() noexcept { - Schedule(GetScheduledFlags() & ~READ); + /* IMPLICIT_FLAGS is erased from the flags so + CancelRead() after ScheduleRead() cancels the whole + event instead of leaving IMPLICIT_FLAGS + scheduled */ + Schedule(GetScheduledFlags() & ~(READ|IMPLICIT_FLAGS)); } void CancelWrite() noexcept { - Schedule(GetScheduledFlags() & ~WRITE); + Schedule(GetScheduledFlags() & ~(WRITE|IMPLICIT_FLAGS)); } /**