use std::thread; use std::sync::{mpsc, Mutex, Arc}; enum Message { NewJob(Job), Terminate } pub struct ThreadPool{ workers: Vec, sender: mpsc::Sender, } type Job = Box; impl ThreadPool { 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(Worker::new(id, Arc::clone(&receiver))); } ThreadPool { workers, sender, } } pub fn execute(&self, f: F) where F: FnOnce() + Send + 'static { let job = Box::new(f); self.sender.send(Message::NewJob(job)).unwrap(); } // pub fn spawn(f: F) -> JoinHandle // where // F: FnOnce() -> T + Send + 'static, // T: Send + 'static // { // } } impl Drop for ThreadPool { fn drop(&mut self) { println!("Sending terminate message to all workers."); for _ in &mut self.workers { self.sender.send(Message::Terminate).unwrap(); } println!("Shutting down all workers."); for worker in &mut self.workers { println!("Shutting down worker {}.", worker.id); if let Some(thread) = worker.thread.take() { thread.join().unwrap(); } } } } struct Worker { id: usize, thread: Option>, } impl Worker { fn new(id: usize, receiver: Arc>>) -> Worker { let thread = 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 {} was told to terminate.", id); break; }, } } }); Worker { id, thread: Some(thread), } } } pub struct Response { header: String, content: String, } impl Response { pub fn new(hdr: &str, cnt: &str) -> Response { Response { header: String::from(hdr), content: String::from(cnt), } } pub fn set_header(&mut self, hdr: &str) { self.header = String::from(hdr); } pub fn get_header(&self) { self.header } pub fn set_content(&mut self, cnt: &str) { self.content = String::from(cnt); } pub fn add_content(&mut self, cnt: &str) { self.content.push_str(cnt); } pub fn get_content(&self) { self.content } } pub struct Route { path: &'static str, action: fn(&&str, &mut Response), } impl Route { fn new(p: String, a: fn(&&str, &mut Response)) { Route { path: p, action: (a), } } }