epollのマンページには、EPOLLET(エッジトリガー)に登録されたfdは、読み取りが行われていない場合、EPOLLINに2回通知するべきではないと記載されています。
したがって、EPOLLINの後、epoll_waitが新しいデータで新しいEPOLLINを返すことができるようになる前に、バッファーを空にする必要があります。
ただし、手付かずのfdsに対して重複したEPOLLINイベントが表示されるため、このアプローチで問題が発生しています。
これはstrace出力です。0x200はEPOLLRDHUPであり、私のglibcヘッダーではまだ定義されていませんが、カーネルで定義されています。
30285 epoll_ctl(3, EPOLL_CTL_ADD, 9, {EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET|0x2000, {u32=9, u64=9}}) = 0
30285 epoll_wait(3, {{EPOLLIN, {u32=9, u64=9}}}, 10, -1) = 1
30285 epoll_wait(3, {{EPOLLIN, {u32=9, u64=9}}}, 10, -1) = 1
30285 epoll_wait(3, <unfinished ...>
30349 epoll_ctl(3, EPOLL_CTL_DEL, 9, NULL) = 0
30306 recv(9, "7u\0\0\10\345\241\312\t\20\f\32\r\10\27\20\2\30\200\10 \31(C0\17\32\r\10\27\20\2\30"..., 20000, 0) = 20000
30349 epoll_ctl(3, EPOLL_CTL_DEL, 9, NULL) = -1 ENOENT (No such file or directory)
30305 recv(9, " \31(C0\17\32\r\10\27\20\2\30\200\10 \31(C0\17\32\r\10\27\20\2\30\200\10 \31("..., 20000, 0) = 10011
したがって、fd番号9を追加した後、ファイル記述子を受け取る前に2つの連続したEPOLLINイベントを受信します。システムコールトレースは、読み取る前にfdを削除する方法を示していますが、イベントごとに1回だけ発生するはずです。
したがって、マンページを正しく読んでいないか、ここで何かが機能しています。