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.
This commit is contained in:
Max Kellermann 2024-04-17 14:45:46 +02:00 committed by Max Kellermann
parent 6830cf9dcf
commit 4d3adaa557

View File

@ -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));
}
/**