use std::{thread, fs}; 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) -> &String { &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) -> &String { &self.content } pub fn add_file_contents(&mut self, filename: &str) { self.set_content(fs::read_to_string(filename).unwrap().as_str()); } } #[derive(Copy, Clone)] pub struct Route { path: &'static str, action: fn(&&str, &mut Response), } impl Route { pub fn new(p: &'static str, a: fn(&&str, &mut Response)) -> Route { Route { path: p, action: a, } } pub fn set_path(&mut self, p: &'static str) { self.path = p; } pub fn get_path(&self) -> &'static str { &self.path } pub fn set_action(&mut self, a: fn(&&str, &mut Response)) { self.action = a; } pub fn get_action(&self) -> fn(&&str, &mut Response) { self.action } } // #[derive(Copy, Clone)] // pub struct RoutesList { // routes: Vec, // } // impl RoutesList { // pub fn new() -> RoutesList { // RoutesList { // routes: Vec::new(), // } // } // pub fn add_route(&mut self, r: &Route) { // self.routes.push(r) // } // pub fn get_routes(&self) -> Vec { // &self.routes // } // pub fn get_copy(&self) -> RoutesList { // self.clone() // } // }