use crate::tasks::{IOCallback, IOEvent};
use crossfire::{MTx, Tx, flavor::Flavor, mpmc};
pub trait Worker<C: IOCallback>: Send + 'static {
fn done(&self, event: Box<IOEvent<C>>);
}
pub struct IOWorkers<C: IOCallback>(pub(crate) MTx<mpmc::Array<Box<IOEvent<C>>>>);
impl<C: IOCallback> IOWorkers<C> {
pub fn new(workers: usize) -> Self {
let (tx, rx) = mpmc::bounded_blocking::<Box<IOEvent<C>>>(100000);
for _i in 0..workers {
let _rx = rx.clone();
std::thread::spawn(move || {
loop {
match _rx.recv() {
Ok(event) => event.callback_unchecked(true),
Err(_) => {
debug!("IOWorkers exit");
return;
}
}
}
});
}
Self(tx)
}
}
impl<C: IOCallback> Clone for IOWorkers<C> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<C: IOCallback> Worker<C> for IOWorkers<C> {
fn done(&self, item: Box<IOEvent<C>>) {
let _ = self.0.send(item);
}
}
impl<C, F> Worker<C> for MTx<F>
where
F: Flavor<Item = Box<IOEvent<C>>>,
C: IOCallback,
{
fn done(&self, item: Box<IOEvent<C>>) {
let _ = self.send(item);
}
}
impl<C, F> Worker<C> for Tx<F>
where
F: Flavor<Item = Box<IOEvent<C>>>,
C: IOCallback,
{
fn done(&self, item: Box<IOEvent<C>>) {
let _ = self.send(item);
}
}
pub struct Inline;
impl<C: IOCallback> Worker<C> for Inline {
fn done(&self, event: Box<IOEvent<C>>) {
event.callback_unchecked(true);
}
}