tokio-rs / tokio

A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
https://tokio.rs
MIT License
26.59k stars 2.45k forks source link

Unreadable `AsyncFd` cannot be polled correctly with `Interest::READABLE` with epoll on Linux #6632

Open XOR-op opened 3 months ago

XOR-op commented 3 months ago

Version tokio v1.38.0

Platform Linux 5.11.0-25-generic, Ubuntu 20.04.1

Description The file descriptor refers to a kernel module, which is not readable but pollable. Calling libc::read on it will receive a EINVAL error. However, this file descriptor supports epoll, and can be correctly polled by EPOLLIN, without any EPOLLERR event triggered. The behaviors of AsyncFd and epoll mismatched.

The following code will hang infinitely while manual calling to epoll will return correct event count:

async_fd.ready(Interest::READABLE | Interest::PRIORITY).await

The following code will return immediately, while no events will be received even if EPOLLERR is registered:

async_fd.ready(Interest::READABLE | Interest::PRIORITY | Interest::ERROR).await

It turns out AsyncFd thinks there are some errors while no error is from epoll.

I hope to know if this is the expected behavior; if it is, is there any workaround to get the same behavior with epoll?

Darksonn commented 3 months ago

The fact that libc::read doesn't work is not an issue, and AsyncFd will not try to call it. However, I'm not sure what the actual issue is.