use std::io;
use std::mem::{drop as unlock, take};
use std::time::Duration;
use crate::kqueue::{Event, Shared, UseEvents};
use crate::lock;
#[derive(Debug)]
pub(crate) struct Completions {
events: Vec<Event>,
}
impl Completions {
pub(crate) fn new(events_capacity: u32) -> Completions {
let events = Vec::with_capacity(events_capacity as usize);
Completions { events }
}
#[allow(clippy::unnecessary_wraps)]
pub(crate) fn poll(&mut self, shared: &Shared, timeout: Option<Duration>) -> io::Result<()> {
self.events.clear();
let timeout = if shared.polling.set_polling(true) {
Some(Duration::ZERO)
} else {
timeout
};
let mut change_list = lock(&shared.change_list);
let mut changes = if change_list.is_empty() {
Vec::new() } else {
take(&mut *change_list)
};
unlock(change_list);
log::trace!(submissions = changes.len(), timeout:?; "waiting for events");
shared.kevent(&mut changes, UseEvents::Some(&mut self.events), timeout);
shared.polling.set_polling(false);
shared.reuse_change_list(changes);
Ok(())
}
pub(crate) fn drop(&mut self, shared: &Shared) {
if let Err(err) = self.poll(shared, Some(Duration::ZERO)) {
log::warn!("error processing last completions: {err}");
}
}
}