jtp 0.1.0

A simple implementation of a thread pool.
Documentation
use std::{
    thread::{self, JoinHandle},
    time::Duration,
};

use crossbeam_channel::Receiver;

use crate::task::Task;

/// A worker holds a thread and a receiver.
pub struct Worker {
    pub(crate) is_core: bool,
    receiver: Receiver<Task>,
    keep_alive_time: Duration,
    thread: JoinHandle<()>,
}

fn create_core_work_thread(receiver: Receiver<Task>, task: Task) -> JoinHandle<()> {
    thread::spawn(move || {
        task.run();
        while let Ok(task) = receiver.recv() {
            task.run();
        }
    })
}

fn create_work_thread(
    receiver: Receiver<Task>,
    task: Task,
    keep_alive_time: Duration,
) -> JoinHandle<()> {
    thread::spawn(move || {
        task.run();
        while let Ok(task) = receiver.recv_timeout(keep_alive_time) {
            task.run();
        }
    })
}

impl Worker {
    #[must_use]
    pub fn new(
        is_core: bool,
        keep_alive_time: Duration,
        receiver: Receiver<Task>,
        task: Task,
    ) -> Self {
        Worker {
            is_core,
            keep_alive_time,
            receiver: receiver.clone(),
            thread: if is_core {
                create_core_work_thread(receiver, task)
            } else {
                create_work_thread(receiver, task, keep_alive_time)
            },
        }
    }

    /// If the `self` worker is idle and is not core, creates a new
    /// thread for the worker to process the given task.
    ///
    /// This will make the `self` worker available again.
    pub(crate) fn restart(&mut self, task: Task) {
        debug_assert!(self.is_finished() && !self.is_core);
        self.thread = create_work_thread(self.receiver.clone(), task, self.keep_alive_time);
    }

    #[inline]
    pub fn is_finished(&self) -> bool {
        self.thread.is_finished()
    }

    #[inline]
    pub(crate) fn join(self) -> thread::Result<()> {
        self.thread.join()
    }
}