1use std::sync::{mpsc, Arc, Mutex};
2
3use crate::worker::Worker;
4
5pub type Job = Box<dyn FnOnce() + Send + 'static>;
6
7pub struct ThreadPool {
8 workers: Vec<Worker>,
9 sender: Option<mpsc::Sender<Job>>,
10}
11
12impl ThreadPool {
13 pub fn new(size: usize) -> Self {
18 assert!(size != 0);
19
20 let (sender, receiver) = mpsc::channel();
21 let receiver = Arc::new(Mutex::new(receiver));
22
23 let mut workers = Vec::with_capacity(size);
24
25 for id in 0..size {
26 workers.push(Worker::new(id, Arc::clone(&receiver)));
27 }
28
29 Self {
30 workers,
31 sender: Some(sender),
32 }
33 }
34
35 pub fn execute<F>(&self, f: F)
48 where
49 F: FnOnce() + Send + 'static,
50 {
51 let job = Box::new(f);
52 self.sender.as_ref().unwrap().send(job).unwrap();
53 }
54}
55
56impl Drop for ThreadPool {
57 fn drop(&mut self) {
58 drop(self.sender.take());
59
60 for worker in &mut self.workers {
61 if let Some(thread) = worker.thread.take() {
62 thread.join().unwrap();
63 }
64 }
65 }
66}