From: Martin Pitt Date: Sun, 19 Sep 2021 09:37:29 +0000 (+0200) Subject: simple-http: Implement ThreadPool messaging X-Git-Url: https://piware.de/gitweb/?p=learn-rust.git;a=commitdiff_plain;h=769d09958d7078847879f96b00c018c93c073072 simple-http: Implement ThreadPool messaging --- diff --git a/simple-http/src/lib.rs b/simple-http/src/lib.rs index ff8bc4f..4b7d736 100644 --- a/simple-http/src/lib.rs +++ b/simple-http/src/lib.rs @@ -1,18 +1,27 @@ use std::thread; +use std::sync::{Arc, mpsc, Mutex}; + +type Job = Box; struct Worker { id: usize, - thread: thread::JoinHandle<()>, + thread: Option>, } impl Worker { - fn new(id: usize) -> Worker { - Worker { id, thread: thread::spawn(|| {}) } + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = Some(thread::spawn(move || loop { + let job = receiver.lock().unwrap().recv().unwrap(); + println!("Worker {} got a job, executing", id); + job(); + })); + Worker { id, thread } } } pub struct ThreadPool { workers: Vec, + sender: mpsc::Sender, } impl ThreadPool { @@ -25,16 +34,31 @@ impl ThreadPool { assert!(size > 0); let mut workers = Vec::with_capacity(size); + let (sender, receiver) = mpsc::channel(); + let receiver = Arc::new(Mutex::new(receiver)); + for id in 0..size { - workers.push(Worker::new(id)); + workers.push(Worker::new(id, Arc::clone(&receiver))); } - ThreadPool { workers } + ThreadPool { workers, sender } } pub fn execute(&self, f: F) where F: FnOnce() + Send + 'static { - thread::spawn(f); + self.sender.send(Box::new(f)).unwrap(); + } +} + +impl Drop for ThreadPool { + fn drop(&mut self) { + for worker in &mut self.workers { + println!("Shutting down worker {}", worker.id); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } } }