-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Allow consumers to implement POSIX AIO sources. #3841
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Unlike every other kqueue event source, POSIX AIO registers events not via kevent(2) but by a different mechanism that needs the kqueue's file descriptor. This commit adds a new `PollAio` type, designed to be used by an external crate that implements a POSIX AIO Future for use with Tokio's reactor. Fixes: tokio-rs#3197
We cannot expose mio types from Tokio at this time (due to the stability differences). Even once Mio hits 1.0, it is not clear that we will. The best strategy to expose aio will be to expose the operations proper (e.g. |
Another option would be to provide an alternate AIO back-end implementation for existing Tokio types (e.g. File). Though, this would require an additional copy. |
This seems like a similar problem to exposing io-uring, which is being being worked on externally: tokio-rs/tokio-uring#1 |
Well yes, the ultimate goal is to merge the AIO stuff into tokio::fs, as an OS-specific implementation of But my concern is that adding all of these methods right away would create more API-instability than adding Since it's only temporary, what if I rename the "aio" feature into "aio-unstable" or something like that? |
Oh, and one other problem. |
Since the strategy in this PR is not feasible, I am closing the PR. You should feel free to reopen or open a new PR if you find a way to address our concerns. |
@Darksonn I can't figure out what you would be willing to accept. This was the smallest and most targeted change I could come up with that would get the job done. Rather than expose mio::Source, I could create a new type tokio::AioSource. It would basically just wrap mio::Source, but perhaps remove the reregister and deregister events. It would be pure syntactic salt, however, and would necessitate much more code that this this PR includes. |
While small changes are good, using traits or types from mio in our public API is not going to be acceptable as they make it impossible to upgrade past mio version 0.7.x. You will find a similar story if you look at how named pipes got included in Tokio — the resulting change there is also rather large. |
So which alternative do you prefer? Adding a tokio::AioSource, or merging all of tokio_file into tokio in one fell swoop? |
I don't have a clear enough image of how those options would look in detail to answer that. Do you have a sketch of how an |
|
Could it be done using only the Another approach is to use the same idea as we are using for io_uring where you can register the uring with Tokio using |
It's not enough for Tokio to expose the kqueue's file descriptor. It also needs to provide a
If I understand correctly, you're suggesting creating a separate kqueue just for AIO, and registering its file descriptor with Tokio's main kqueue, then polling it in a separate crate whenever Tokio's main kqueue says it's readable? I don't know if you can use kqueue that way. But even if you can, it would require duplicating an awful lot of Tokio's core reactor code. And it would be less efficient than using a single kqueue. |
The long-term target is Tokio provides a nice API to cover the aio cases. We are mostly discussing the steps to get there. As I see it, there are two options: a) implement as a separate lib using the strategy of registering a kqueue instance w/ I think I'm OK with either if @Darksonn is. From my understanding, something like AsyncFd would work if it exposes the kqueue fd + the token, so it would look very roughly something like: struct AioSource { ... }
impl AioSource {
fn new() -> io::Result<AioSource> { ... }
fn kqueue_fd(&self) -> RawFd { ... }
// `Token` might end up just being `usize`.
fn token(&self) -> Token { ... }
async fn ready(&self, interest: Interest) -> AioReadyGuard { ... }
}
impl AioReadyGuard {
fn readiness(&self) -> Ready { ... }
} I would suggest opening a design issue w/ an API proposal before doing work either way. |
@carllerche I'm not sure how you intend that |
Unlike every other kqueue event source, POSIX AIO registers events not
via kevent(2) but by a different mechanism that needs the kqueue's file
descriptor. This commit adds a new
PollAio
type, designed to be usedby an external crate that implements a POSIX AIO Future for use with
Tokio's reactor.
Fixes: #3197
Motivation
With Tokio 0.1 and 0.2,
PollEvented
was sufficiently powerful to allow external crates to implement a POSIX AIO event source. Beginning with Tokio 0.3,PollEvented
became private, and it also lost some needed functionality. Thus, there was no possible way for a consumer to use POSIX AIO with Tokio.Solution
This PR restores that ability. While leaving the actual implementation for an external crate, it adds just enough functionality for the external crate to hook in. It deliberately does not expose all of
PollEvented
, so as not to encourage consumers to use that type overAsyncFd
. Instead, it creates a new, dedicated type.