feat(API): Use mio::Token based polling

Avoid polling every single IO source to collect events,
poll those specific IO sources mio tells us about.
This commit is contained in:
Karolin Varner
2024-08-18 21:19:44 +02:00
parent 53e560191f
commit 77760d71df
13 changed files with 403 additions and 98 deletions

View File

@@ -52,6 +52,56 @@ impl<T, E: TryIoErrorKind> TryIoResultKindHintExt<T> for Result<T, E> {
}
}
pub trait SubstituteForIoErrorKindExt<T>: Sized {
type Error;
fn substitute_for_ioerr_kind_with<F: FnOnce() -> T>(
self,
kind: io::ErrorKind,
f: F,
) -> Result<T, Self::Error>;
fn substitute_for_ioerr_kind(self, kind: io::ErrorKind, v: T) -> Result<T, Self::Error> {
self.substitute_for_ioerr_kind_with(kind, || v)
}
fn substitute_for_ioerr_interrupted_with<F: FnOnce() -> T>(
self,
f: F,
) -> Result<T, Self::Error> {
self.substitute_for_ioerr_kind_with(io::ErrorKind::Interrupted, f)
}
fn substitute_for_ioerr_interrupted(self, v: T) -> Result<T, Self::Error> {
self.substitute_for_ioerr_interrupted_with(|| v)
}
fn substitute_for_ioerr_wouldblock_with<F: FnOnce() -> T>(
self,
f: F,
) -> Result<T, Self::Error> {
self.substitute_for_ioerr_kind_with(io::ErrorKind::WouldBlock, f)
}
fn substitute_for_ioerr_wouldblock(self, v: T) -> Result<T, Self::Error> {
self.substitute_for_ioerr_wouldblock_with(|| v)
}
}
impl<T, E: TryIoErrorKind> SubstituteForIoErrorKindExt<T> for Result<T, E> {
type Error = E;
fn substitute_for_ioerr_kind_with<F: FnOnce() -> T>(
self,
kind: io::ErrorKind,
f: F,
) -> Result<T, Self::Error> {
match self.try_io_err_kind_hint() {
Ok(v) => Ok(v),
Err((_, Some(k))) if k == kind => Ok(f()),
Err((e, _)) => Err(e),
}
}
}
/// Automatically handles `std::io::ErrorKind::Interrupted`.
///
/// - If there is no error (i.e. on `Ok(r)`), the function will return `Ok(Some(r))`