]> git.proxmox.com Git - rustc.git/blame - src/doc/book/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / src / doc / book / listings / ch20-web-server / no-listing-06-fix-threadpool-drop / src / lib.rs
CommitLineData
923072b8
FG
1use std::{
2 sync::{mpsc, Arc, Mutex},
3 thread,
4};
74b04a01
XL
5
6pub struct ThreadPool {
7 workers: Vec<Worker>,
8 sender: mpsc::Sender<Job>,
9}
10
11type Job = Box<dyn FnOnce() + Send + 'static>;
12
13impl ThreadPool {
14 /// Create a new ThreadPool.
15 ///
16 /// The size is the number of threads in the pool.
17 ///
18 /// # Panics
19 ///
20 /// The `new` function will panic if the size is zero.
21 pub fn new(size: usize) -> ThreadPool {
22 assert!(size > 0);
23
24 let (sender, receiver) = mpsc::channel();
25
26 let receiver = Arc::new(Mutex::new(receiver));
27
28 let mut workers = Vec::with_capacity(size);
29
30 for id in 0..size {
31 workers.push(Worker::new(id, Arc::clone(&receiver)));
32 }
33
34 ThreadPool { workers, sender }
35 }
36
37 pub fn execute<F>(&self, f: F)
38 where
39 F: FnOnce() + Send + 'static,
40 {
41 let job = Box::new(f);
42
43 self.sender.send(job).unwrap();
44 }
45}
46
47// ANCHOR: here
48impl Drop for ThreadPool {
49 fn drop(&mut self) {
50 for worker in &mut self.workers {
51 println!("Shutting down worker {}", worker.id);
52
53 if let Some(thread) = worker.thread.take() {
54 thread.join().unwrap();
55 }
56 }
57 }
58}
59// ANCHOR_END: here
60
61struct Worker {
62 id: usize,
63 thread: Option<thread::JoinHandle<()>>,
64}
65
66impl Worker {
67 fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
68 let thread = thread::spawn(move || loop {
69 let job = receiver.lock().unwrap().recv().unwrap();
70
923072b8 71 println!("Worker {id} got a job; executing.");
74b04a01
XL
72
73 job();
74 });
75
76 Worker {
77 id,
78 thread: Some(thread),
79 }
80 }
81}