fmodsilo_server 0.1.0

FModSilo language server provides language features for Factorio mod development.
Documentation
use std::{thread::{JoinHandle, self}, sync::{mpsc, Arc, Mutex}};

type Task = Box<dyn FnOnce() + Send + 'static>;

enum Message {
    Task(Task),
    Terminate
}

pub struct ThreadPool {
    threads: Vec<Option<JoinHandle<()>>>,
    transmitter: mpsc::Sender<Message>
}

impl ThreadPool {
    pub fn new(count: usize) -> ThreadPool {
        assert!(count > 0);

        let mut threads = Vec::with_capacity(count);

        let (transmitter, receiver) = mpsc::channel();
        let receiver = Arc::new(Mutex::new(receiver));

        for _ in 0..count {
            let rec = Arc::clone(&receiver);

            threads.push(Some(thread::spawn(move || {
                loop {
                    let message = rec.lock().unwrap().recv().unwrap();

                    match message {
                        Message::Task(job) => job(),
                        Message::Terminate => break
                    };
                }
            })));
        }

        ThreadPool{ threads, transmitter }
    }

    pub fn execute<F: FnOnce() + Send + 'static>(&self, func: F) {
        self.transmitter.send(Message::Task(Box::new(func))).unwrap();
    }
}

impl Drop for ThreadPool {
    fn drop(&mut self) {
        for _ in &self.threads {
            self.transmitter.send(Message::Terminate).unwrap();
        }

        for handle in &mut self.threads {
            if let Some(thr) = handle.take() {
                thr.join().unwrap();
            }
        }
    }
}