-
Notifications
You must be signed in to change notification settings - Fork 226
Description
The current Epoll API is good; however, it's not compatible with the idea of a static reactor. With the current "context" system, you have to choose between a BorrowedFd (which is difficult to do for 'static without leakage) or an OwnedFd (which makes the source inaccessible for the duration of the wait). I filed #471; however, that's a band-aid solution at best. It would be nice to be able to rework the API so that it can be stored in a 'static reactor, while also not forcing every source that interacts with it to be 'static or owned. Given that #472 will probably lead to a breaking change, it's a good time to talk about this.
The idea I had was something to the tune of a Source structure, like this:
pub struct Source<T> {
/// The actual data.
data: T,
/// Reference to the `Epoll` file descriptor.
epoll: &'static EpollRef,
}An object can become a Source by registering itself into the Epoll/Kqueue/whatever, and dropping the Source or moving the data out of the Source causes it to be removed from the poller. This forces the poller to be static, but with the Context system we can make it optional in this case.
Then we can rework the Context trait to take a lifetime, like so:
pub trait Context<'a> {
fn encode(&'a self, ...) { ... }
}
impl<'a> Context<'a> for Borrowed<'a> { ... }
impl Context<'static> for SourceContext { ... }...so that we can be sure that our context that uses Sources is always 'static.
At this point, I'm not sure where to go from here. I tried to implement this pattern on top of the current system, but I ran into issues on how to acquire a Source without taking ownership of it or constricting it to a lifetime.