issue #320: ignore kqueue events marked KQ_EV_ERROR.

Since BasicStream.close() invokes _stop_transmit() followed by
os.close(), and KqueuePoller._stop_transmit() defers the unsubscription
until the IO loop resumes, kqueue generates an error event for the
associated FD, even though the changelist includes an unsubscription
command for the FD.

We could fix this by deferring close() until after the IO loop has run
once (simply by calling .defer()), but that generates extra wakeups for
no real reason.

Instead simply notice the error event and log it, rather than treating
it as a legitimate event.

Another approach to fixing this would be to process
_stop_receive()/_stop_transmit() eagerly, however that entails making
more syscalls.

Closes #320.
pull/322/head^2
David Wilson 6 years ago
parent bb74217604
commit 76caf7d41d

@ -566,7 +566,10 @@ class KqueuePoller(mitogen.core.Poller):
changelist, 32, timeout)
for event in events:
fd = event.ident
if event.filter == select.KQ_FILTER_READ and fd in self._rfds:
if event.flags & select.KQ_EV_ERROR:
LOG.debug('ignoring stale event for fd %r: errno=%d: %s',
fd, event.data, errno.errorcode.get(event.data))
elif event.filter == select.KQ_FILTER_READ and fd in self._rfds:
# Events can still be read for an already-discarded fd.
mitogen.core._vv and IOLOG.debug('%r: POLLIN: %r', self, fd)
yield self._rfds[fd]

Loading…
Cancel
Save