X-Git-Url: https://piware.de/gitweb/?p=learn-rust.git;a=blobdiff_plain;f=simple-http%2Fsrc%2Flib.rs;h=3c5caa679a3e4525d3147585dde045a859b92e7d;hp=ff8bc4f3f8f63faecf47626d0f3a1ecff1082902;hb=4b27e7395888e450ce52e74bf259715105f3071c;hpb=4d4ba2d5f703969851742798e79e16333fb9ca9a;ds=inline diff --git a/simple-http/src/lib.rs b/simple-http/src/lib.rs index ff8bc4f..3c5caa6 100644 --- a/simple-http/src/lib.rs +++ b/simple-http/src/lib.rs @@ -1,18 +1,42 @@ use std::thread; +use std::sync::{Arc, mpsc, Mutex}; + +type Job = Box; + +enum Message { + NewJob(Job), + Terminate, +} 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 message = receiver.lock().unwrap().recv().unwrap(); + + match message { + Message::NewJob(job) => { + println!("Worker {} got a job, executing", id); + job(); + }, + + Message::Terminate => { + println!("Worker {} got terminated", id); + break; + } + } + })); + Worker { id, thread } } } pub struct ThreadPool { workers: Vec, + sender: mpsc::Sender, } impl ThreadPool { @@ -25,16 +49,35 @@ 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(Message::NewJob(Box::new(f))).unwrap(); + } +} + +impl Drop for ThreadPool { + fn drop(&mut self) { + for _ in &self.workers { + self.sender.send(Message::Terminate).unwrap(); + } + + for worker in &mut self.workers { + println!("Shutting down worker {}", worker.id); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } } }