BUG/MAJOR: polling: do not set speculative events on ERR nor HUP
Errors and Hangups are sticky events, which means that once they're
detected, we never clear them, allowing them to be handled later if
needed.
Till now when an error was reported, it used to register a speculative
I/O event for both recv and send. Since the connection had not requested
such events, it was not able to detect a change and did not clear them,
so the events were called in loops until a timeout caused their owner
task to die.
So this patch does two things :
- stop registering spec events when no I/O activity was requested,
so that we don't end up with non-disablable polling state ;
- keep the sticky polling flags (ERR and HUP) when leaving the
connection handler so that an error notification doesn't
magically become a normal recv() or send() report once the
event is converted to a spec event.
It is normally not needed to make the connection handler emit an
error when it detects POLL_ERR because either a registered data
handler will have done it, or the event will be disabled by the
wake() callback.
diff --git a/src/ev_kqueue.c b/src/ev_kqueue.c
index 54c52c2..36a7b7f 100644
--- a/src/ev_kqueue.c
+++ b/src/ev_kqueue.c
@@ -152,10 +152,10 @@
* them so that if nothing can be done we don't need
* to poll again.
*/
- if (fdtab[fd].ev & (FD_POLL_IN|FD_POLL_HUP|FD_POLL_ERR))
+ if (fdtab[fd].ev & FD_POLL_IN)
fd_ev_set(fd, DIR_RD);
- if (fdtab[fd].ev & (FD_POLL_OUT|FD_POLL_ERR))
+ if (fdtab[fd].ev & FD_POLL_OUT)
fd_ev_set(fd, DIR_WR);
fdtab[fd].iocb(fd);