Не факт, что edge triggered в том чистом виде, как он реализован в epoll
лучше level triggered. Например, если на момент добавления сокета в epoll
данные уже есть в сокете, то edge triggered epoll про них не раскажет.
Приходится делать лишний read после добавления. Кроме того, есть и просто
ошибка реализации edge triggered, когда нужно делать read до получения
EAGAIN, иначе можно пропустить EOF.
А вот EV_CLEAR в kqueue сделан явно с применением мозга.
Автор libev тоже не очень лестно высказывается насчет epoll. В частности он пишет об ошибках в его работе:
The epoll mechanism deserves honorable mention as the most misdesigned of the more advanced event mechanisms: mere annoyances include silently dropping file descriptors, requiring a system call per change per file descriptor (and unnecessary guessing of parameters), problems with dup, returning before the timeout value, resulting in additional iterations (and only giving 5ms accuracy while select on the same platform gives 0.1ms) and so on. Epoll is also notoriously buggy - embedding epoll fds should work, but of course doesn't, and epoll just loves to report events for totally different file descriptors (even already closed ones, so one cannot even remove them from the set) than registered in the set (especially on SMP systems). Epoll also erroneously rounds down timeouts, but gives you no way to know when and by how much, so sometimes you have to busy-wait because epoll returns immediately despite a nonzero timeout. And last not least, it also refuses to work with some file descriptors which work perfectly fine with select (files, many character devices...).
Хотелось бы узнать по Вашему опыту, такие проблемы действительно имеют место? Или может они исправлены в более свежих версиях ядра?