use std::time::Duration;
use crate::completion::CompletionEvent;
use crate::error::{Error, Result};
use crate::{BackendFactory, Ring};
#[derive(Clone)]
pub struct CallbackDrain<F: BackendFactory> {
ring: Ring<F>,
limit: usize,
}
impl<F: BackendFactory> CallbackDrain<F> {
#[must_use]
pub fn new(ring: Ring<F>, limit: usize) -> Self {
Self {
ring,
limit: limit.max(1),
}
}
pub fn drain<C>(&self, timeout: Option<Duration>, mut callback: C) -> Result<usize>
where
C: FnMut(CompletionEvent),
{
let mut processed = 0;
for index in 0..self.limit {
let wait = if index == 0 {
timeout
} else {
Some(Duration::from_millis(1))
};
match self.ring.complete(wait) {
Ok(event) => {
callback(event);
processed += 1;
}
Err(Error::Timeout { .. }) if processed > 0 => break,
Err(error) => return Err(error),
}
}
Ok(processed)
}
}