pub use super::types::ExecuteError;
use super::{
types::{Message, MessageSender},
worker::Worker,
};
use std::sync::{mpsc, Arc, Mutex};
use log::*;
pub struct ThreadPool {
workers: Vec<Worker>,
sender: MessageSender,
}
impl ThreadPool {
pub fn new(size: usize) -> ThreadPool {
trace!("Creating ThreadPool...");
assert!(size > 0);
let (sender, receiver) = mpsc::channel();
let receiver = Arc::new(Mutex::new(receiver));
let mut workers = Vec::with_capacity(size);
trace!("Creating ThreadPool with size {}...", size);
for id in 0..size {
workers.push(Worker::new(id, Arc::clone(&receiver)));
}
trace!("ThreadPool created");
ThreadPool { workers, sender }
}
pub fn execute<F>(&self, f: F)
where
F: FnOnce() + Send + 'static,
{
let job = Box::new(f);
self.sender.send(Message::NewJob(job)).unwrap();
trace!("Job added to the queue");
}
pub fn join(&mut self) {
trace!("Joining workers...");
for _ in &mut self.workers {
self.sender.send(Message::Terminate).unwrap();
}
trace!("Terminate message sent to all workers");
for worker in &mut self.workers {
if let Some(thread) = worker.thread.take() {
thread.join().unwrap();
trace!("Worker #{} joined", worker.id);
}
}
trace!("Workers joined");
}
}