webserver_rust/
lib.rs

1//!
2//! # webserver
3//! 
4//! One simple webserver. Learn from https://www.youtube.com/watch?v=TOyiliDaK30&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=110.
5
6use std::thread;
7use std::sync::mpsc;
8use std::sync::Arc;
9use std::sync::Mutex;
10
11enum Message {
12    NewJob(Job),
13    Terminate,
14}
15
16pub struct ThreadPool
17{
18    workers: Vec<Worker>,
19    sender:mpsc::Sender<Message>,
20}
21
22
23// struct Job;
24
25trait FnBox {
26    fn call_box(self:Box<Self>);
27}
28
29impl<F:FnOnce()> FnBox for F{
30    fn call_box(self:Box<F>){
31        (*self)()
32    }
33}
34
35type Job = Box<dyn FnBox+ Send+ 'static>;
36
37impl ThreadPool {
38    /// Create a new ThreadPool
39    /// 
40    /// The size is the number of threads in the pool.
41    /// 
42    /// 
43    pub fn new(size:usize)->ThreadPool{
44        assert!(size>0);
45        let mut workers = Vec::with_capacity(size);
46
47        let (sender,receiver) = mpsc::channel();
48        let receiver = Arc::new(Mutex::new(receiver));
49        
50        for id in 0..size{
51            workers.push(Worker::new(id,Arc::clone(&receiver)));
52        }
53        ThreadPool { workers,sender }
54    }
55
56    pub fn execute<F>(&self,f:F)
57    where
58        F:FnOnce() + Send + 'static
59    {
60        let job = Box::new(f);
61        self.sender.send(Message::NewJob(job)).unwrap();
62
63    }
64}
65
66struct Worker {
67    id: usize,
68    thread: Option<thread::JoinHandle<()>>,
69}
70
71impl Worker {
72    fn new(id: usize,receiver:Arc<Mutex<mpsc::Receiver<Message>>>)->Worker{
73
74        let thread = thread::spawn(move|| loop{
75            let message = receiver.lock().unwrap().recv().unwrap();
76            match message {
77                Message::NewJob(job) => {
78                    job.call_box();
79                },
80                Message::Terminate => {
81                    println!("worker {} was told to terminate.",id);
82                    break;
83                }
84            }
85            
86        });
87
88        Worker{id,thread:Some(thread)}
89    }
90}
91
92impl Drop for ThreadPool {
93    fn drop(&mut self) {
94        for _ in &mut self.workers {
95            self.sender.send(Message::Terminate).unwrap();
96        }
97
98        for worker in &mut self.workers {
99
100            if let Some(thread) = worker.thread.take(){
101                thread.join().unwrap();
102            };
103        }
104    }
105}