http_server_rs/
connectionthreadpool.rs1use std::{sync::{mpsc::{self, Receiver, Sender}, Arc, Mutex}, thread::{self, JoinHandle}};
2
3use crate::executor::Executor;
4
5
6pub struct ThreadPool {
7 sender: Option<Sender<Job>>,
8 workers: Vec<Worker>,
9}
10
11impl ThreadPool {
12
13 pub fn new(thread_count : usize) -> ThreadPool {
14 assert!(thread_count > 0);
15
16 let mut workers = Vec::with_capacity(thread_count);
17 let (sender, receiver) = mpsc::channel();
18
19 let arc_rec = Arc::new(Mutex::new(receiver));
20 for _ in 0..thread_count {
21 workers.push(Worker::new(
22 Arc::clone(&arc_rec)));
24 }
25 let sender = Some(sender);
27 return ThreadPool {sender, workers};
28 }
29
30}
31
32impl Executor for ThreadPool {
33 fn execute_mut<F>(&mut self, job : F)
34 where F : FnOnce() + Send + 'static {
35 self.sender.as_ref().unwrap().send(Box::new(job)).unwrap();
36 }
37}
38
39impl Drop for ThreadPool {
40 fn drop(&mut self) {
41 while self.workers.len() > 0 {
42 let worker = self.workers.remove(0);
43 worker.thread.join().unwrap();
44 }
46 }
47}
48
49type Job = Box<dyn FnOnce() + Send + 'static>;
50
51struct Worker {
52 thread: JoinHandle<()>,
54}
55
56impl Worker {
57 fn new(
58 employer : Arc<Mutex<Receiver<Job>>>) -> Worker {
60 let thread = thread::spawn(move|| {
61 loop {
62 let value = employer.lock().unwrap().recv();
63 match value {
64 Ok(job) => {
65 job();
67 }
68 Err(_) => {
69 break;
71 }
72 }
73 }
74 });
75
76 Worker {
77 thread }
79 }
80}