Browse files

Fixing linux poller.

In short: epoll royally sucks.

The longer version: epoll doesn't allow 2 separate events to be
maintained per fd. If we register an fd for read, and then decide
to register it for write too, the later will overwrite the original
registered read event unless we register READ|WRITE. It seems
harmless but it's not. When we register for READ|WRITE and only
a READ event arrives, we first receive the READ event, and in the
next epoll_wait if a READ + WRITE event occurs we'll receive READ|WRITE
because the original registered event is READ|WRITE. What this means
is that we received READ twice here, once as READ and the second
time when a WRITE & READ occured, READ|WRITE. We were not expecting
the second READ event and w'ell have to ignore it.

This behavior happens because we are not passing EPOLLONESHOT. The
reason we don't want to do this is that the EPOLLONESHOT will get applied
to both events (read + write) when we only need it for one. Ex: If we
register for a READ event, followed by registering WRITE event
READ|WRITE|EPOLLONESHOT this will mean if either of the READ or WRITE
event occurs it will be EPOLLONESHOT and the second event will need
to be registered. I certainly don't want to track such events and
reregister them. Hence I am going with the first solution
by not use EPOLLONESHOT and ignore events I am not expecting.

If only epoll supports fd+event as a key rather than fd only.
  • Loading branch information...
1 parent 7657af6 commit e07c1412c903a40caa1247ac2c1a783bc10fc92b @halayli committed Apr 9, 2012
Showing with 93 additions and 269 deletions.
  1. +93 −269 coro/linux_poller.pyx
Oops, something went wrong.

0 comments on commit e07c141

Please sign in to comment.