X-Git-Url: https://piware.de/gitweb/?p=learn-rust.git;a=blobdiff_plain;f=simple-http%2Fsrc%2Flib.rs;h=4b7d7362afa241b94f34a2e3166f6c44288eb90a;hp=ff8bc4f3f8f63faecf47626d0f3a1ecff1082902;hb=769d09958d7078847879f96b00c018c93c073072;hpb=4d4ba2d5f703969851742798e79e16333fb9ca9a 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(); + } + } } }