Rust mio 甚至在 stdin 上也总是报告

rust mio always reports even on stdin

我尝试向 mio 添加一些 fds,包括标准输入。 我的应用程序在尝试从 stdin 读取时卡住了,在我从 mio 收到事件后,stdin 是可读的。

当我跟踪应用程序时,我注意到,mio 使用 epoll_wait 并且那个系统调用 returns 立即。

strace -e trace=epoll_create,epoll_ctl,epoll_wait,read,epoll_create1 ./target/debug/ongybar

epoll_create1(EPOLL_CLOEXEC)            = 6
epoll_ctl(6, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLET, {u32=4294967295, u64=18446744073709551615}}) = 0
epoll_ctl(6, EPOLL_CTL_ADD, 3, {EPOLLIN, {u32=0, u64=0}}) = 0
epoll_ctl(6, EPOLL_CTL_ADD, 0, {EPOLLIN, {u32=0, u64=0}}) = 0
epoll_ctl(6, EPOLL_CTL_ADD, 4, {EPOLLIN, {u32=4, u64=4}}) = 0
epoll_wait(6, [{EPOLLIN, {u32=4, u64=4}}], 4, -1) = 1
read(4, "[...], 8192) = 1004
epoll_wait(6, [{EPOLLIN, {u32=0, u64=0}}], 4, -1) = 1
read(0, 

我正在使用的完整代码在 github

我的强烈猜测是,不是 fd 0 (stdin) 而是 fd 3 变得可读: 这里

epoll_ctl(6, EPOLL_CTL_ADD, 3, {EPOLLIN, {u32=0, u64=0}}) = 0
epoll_ctl(6, EPOLL_CTL_ADD, 0, {EPOLLIN, {u32=0, u64=0}}) = 0

你可以看到,fd 0 和 3 注册了 epoll_data u32/u64 = 0.

这里

epoll_wait(6, [{EPOLLIN, {u32=0, u64=0}}], 4, -1) = 1

你只能推断,u32/u64=0的两个注册文件描述符之一现在是可读的,但你不能在这里区分fd 0和fd 3!并且由于从标准输入块读取它必须是 fd 3.

解决方案是为每个文件描述符使用 u32/u64 的唯一标识符,以便能够正确识别具有 activity.

的正确文件描述符