ncd 0.1.2

Nate's Central Dispatch. Rust concurrency library.
Documentation
use std::{panic, sync::Arc, thread};

use super::TaskQueue;

/// General purpose threadpool. Panics in threads are caught.
pub struct ThreadPool {
    task_queue: Arc<TaskQueue>,
}

impl ThreadPool {
    /// Creates a new threadpool.
    ///
    /// # Notes
    /// * Thread names will be "name_patter-X", where X is the number
    ///   in creation order.
    ///
    /// # Panics
    /// * Will panic if `std::thread::Builder` fails.
    pub fn new(name_pattern: &str, num_threads: usize) -> Self {
        let task_queue = Arc::new(TaskQueue::new());

        for i in 0..num_threads {
            let task_queue = task_queue.clone();
            thread::Builder::new()
                .name(format!("{name_pattern}-{i}"))
                .spawn(move || {
                    worker_loop(task_queue);
                })
                .unwrap();
        }

        ThreadPool { task_queue }
    }

    /// Submit a task to the threadpool.
    pub fn submit<F>(&self, task: F)
    where
        F: FnOnce() + Send + 'static,
    {
        self.task_queue.push(Box::new(task));
    }
}

fn worker_loop(task_queue: Arc<TaskQueue>) {
    loop {
        let task = task_queue.pop();
        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| {
            task();
        }));
    }
}