#[macro_export]
macro_rules! batch_register {
($poll:ident, $token_fac:ident, $( $source:expr ),* $(,)?) => {
{
$(
$source.register($poll, $token_fac)?;
)*
$crate::Result::<_>::Ok(())
}
};
}
#[macro_export]
macro_rules! batch_reregister {
($poll:ident, $token_fac:ident, $( $source:expr ),* $(,)?) => {
{
$(
$source.reregister($poll, $token_fac)?;
)*
$crate::Result::<_>::Ok(())
}
};
}
#[macro_export]
macro_rules! batch_unregister {
($poll:ident, $( $source:expr ),* $(,)?) => {
{
$(
$source.unregister($poll)?;
)*
$crate::Result::<_>::Ok(())
}
};
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use crate::{
ping::{make_ping, PingSource},
EventSource, PostAction,
};
struct BatchSource {
ping0: PingSource,
ping1: PingSource,
ping2: PingSource,
}
impl EventSource for BatchSource {
type Event = usize;
type Metadata = ();
type Ret = ();
type Error = Box<dyn std::error::Error + Sync + Send>;
fn process_events<F>(
&mut self,
readiness: crate::Readiness,
token: crate::Token,
mut callback: F,
) -> Result<crate::PostAction, Self::Error>
where
F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
{
self.ping0
.process_events(readiness, token, |_, m| callback(0, m))?;
self.ping1
.process_events(readiness, token, |_, m| callback(1, m))?;
self.ping2
.process_events(readiness, token, |_, m| callback(2, m))?;
Ok(PostAction::Continue)
}
fn register(
&mut self,
poll: &mut crate::Poll,
token_factory: &mut crate::TokenFactory,
) -> crate::Result<()> {
crate::batch_register!(poll, token_factory, self.ping0, self.ping1, self.ping2)
}
fn reregister(
&mut self,
poll: &mut crate::Poll,
token_factory: &mut crate::TokenFactory,
) -> crate::Result<()> {
crate::batch_reregister!(poll, token_factory, self.ping0, self.ping1, self.ping2)
}
fn unregister(&mut self, poll: &mut crate::Poll) -> crate::Result<()> {
crate::batch_unregister!(poll, self.ping0, self.ping1, self.ping2)
}
}
#[test]
fn test_batch_operations() {
let mut fired = [false; 3];
let (send0, ping0) = make_ping().unwrap();
let (send1, ping1) = make_ping().unwrap();
let (send2, ping2) = make_ping().unwrap();
let top = BatchSource {
ping0,
ping1,
ping2,
};
let mut event_loop = crate::EventLoop::<[bool; 3]>::try_new().unwrap();
let handle = event_loop.handle();
let token = handle
.insert_source(top, |idx, _, fired| {
fired[idx] = true;
})
.unwrap();
send0.ping();
send1.ping();
send2.ping();
event_loop
.dispatch(Duration::new(0, 0), &mut fired)
.unwrap();
assert_eq!(fired, [true; 3]);
fired = [false; 3];
handle.update(&token).unwrap();
send0.ping();
send1.ping();
send2.ping();
event_loop
.dispatch(Duration::new(0, 0), &mut fired)
.unwrap();
assert_eq!(fired, [true; 3]);
fired = [false; 3];
handle.remove(token);
send0.ping();
send1.ping();
send2.ping();
event_loop
.dispatch(Duration::new(0, 0), &mut fired)
.unwrap();
assert_eq!(fired, [false; 3]);
}
}