use std::thread::{JoinHandle,spawn};
use crate::channel::ReceiverWrapper;
use crate::Counter;
pub enum Message {
Job {
job: Box<dyn Job<'static>>,
global_counter: Counter,
scope_counter: Option<Counter>,
},
Shutdown,
}
pub trait Job<'scope>: FnOnce() + Send + 'scope {}
impl<'scope, T> Job<'scope> for T
where T: FnOnce() + Send + 'scope {}
pub struct Worker(Option<JoinHandle<()>>);
impl Worker {
pub fn new(
receiver: ReceiverWrapper<Message>,
) -> Worker {
let thread = spawn(move || loop {
let message = receiver.recv();
match message {
Ok(Message::Job { job, global_counter, scope_counter }) => {
job();
global_counter.dec();
if let Some(scope) = scope_counter {
scope.dec();
}
}
Ok(Message::Shutdown) => break,
Err(err) => panic!("Receive error: {err}"),
}
});
Worker(Some(thread))
}
pub fn shutdown(&mut self) {
if let Some(thread) = self.0.take() {
thread.join().unwrap();
}
}
}