use std::{sync::{mpsc, Arc, Mutex}, thread}; pub mod leb128; pub mod status; pub mod http; pub mod dns; pub use status::MinecraftStatus; pub struct ThreadPool { workers: Vec, sender: Option>, } type Job = Box; impl ThreadPool { // Create a new ThreadPool with `size` available threads. // // # Panics // // `new` will panic if `size` is zero. pub fn new(size: usize) -> ThreadPool { assert!(size > 0); let (sender, receiver) = mpsc::channel(); let receiver = Arc::new(Mutex::new(receiver)); let mut workers = Vec::with_capacity(size); for id in 0..size { workers.push(ThreadWorker::new(id, Arc::clone(&receiver))); } ThreadPool { workers, sender: Some(sender) } } pub fn execute(&self, f: F) where F: FnOnce() + Send + 'static { let job = Box::new(f); self.sender.as_ref().unwrap().send(job).unwrap(); } } impl Drop for ThreadPool { fn drop(&mut self) { drop(self.sender.take()); for worker in &mut self.workers.drain(..) { println!("Shutting down worker {}", worker.id); worker.thread.join().unwrap(); } } } struct ThreadWorker { id: usize, thread: thread::JoinHandle<()>, } impl ThreadWorker { fn new(id: usize, receiver: Arc>>) -> ThreadWorker { let thread = thread::spawn(move || loop { let msg = receiver.lock().unwrap().recv(); match msg { Ok(job) => { // println!("Job received by worker {id}"); job(); } Err(_) => { // println!("Worker {id} disconnected. Shutting down..."); break; } } }); ThreadWorker { id, thread } } }