cs431_homework/hello_server/
thread_pool.rs

1//! Thread pool that joins all thread when dropped.
2
3// NOTE: Crossbeam channels are MPMC, which means that you don't need to wrap the receiver in
4// Arc<Mutex<..>>. Just clone the receiver and give it to each worker thread.
5use std::sync::{Arc, Condvar, Mutex};
6use std::thread;
7
8use crossbeam_channel::{Sender, unbounded};
9
10struct Job(Box<dyn FnOnce() + Send + 'static>);
11
12#[derive(Debug)]
13struct Worker {
14    _id: usize,
15    thread: Option<thread::JoinHandle<()>>,
16}
17
18impl Drop for Worker {
19    /// When dropped, the thread's `JoinHandle` must be `join`ed.  If the worker panics, then this
20    /// function should panic too.
21    ///
22    /// NOTE: The thread is detached if not `join`ed explicitly.
23    fn drop(&mut self) {
24        todo!()
25    }
26}
27
28/// Internal data structure for tracking the current job status. This is shared by worker closures
29/// via `Arc` so that the workers can report to the pool that it started/finished a job.
30#[derive(Debug, Default)]
31struct ThreadPoolInner {
32    job_count: Mutex<usize>,
33    empty_condvar: Condvar,
34}
35
36impl ThreadPoolInner {
37    /// Increment the job count.
38    fn start_job(&self) {
39        todo!()
40    }
41
42    /// Decrement the job count.
43    fn finish_job(&self) {
44        todo!()
45    }
46
47    /// Wait until the job count becomes 0.
48    ///
49    /// NOTE: We can optimize this function by adding another field to `ThreadPoolInner`, but let's
50    /// not care about that in this homework.
51    fn wait_empty(&self) {
52        todo!()
53    }
54}
55
56/// Thread pool.
57#[derive(Debug)]
58pub struct ThreadPool {
59    _workers: Vec<Worker>,
60    job_sender: Option<Sender<Job>>,
61    pool_inner: Arc<ThreadPoolInner>,
62}
63
64impl ThreadPool {
65    /// Create a new ThreadPool with `size` threads.
66    ///
67    /// # Panics
68    ///
69    /// Panics if `size` is 0.
70    pub fn new(size: usize) -> Self {
71        assert!(size > 0);
72
73        todo!()
74    }
75
76    /// Execute a new job in the thread pool.
77    pub fn execute<F>(&self, f: F)
78    where
79        F: FnOnce() + Send + 'static,
80    {
81        todo!()
82    }
83
84    /// Block the current thread until all jobs in the pool have been executed.
85    ///
86    /// NOTE: This method has nothing to do with `JoinHandle::join`.
87    pub fn join(&self) {
88        todo!()
89    }
90}
91
92impl Drop for ThreadPool {
93    /// When dropped, all worker threads' `JoinHandle` must be `join`ed. If the thread panicked,
94    /// then this function should panic too.
95    fn drop(&mut self) {
96        todo!()
97    }
98}