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 Source
s 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.