Unnamed repository; edit this file 'description' to name the repository.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use std::sync::Arc;

use crate::{
    MacroDylib, ProcMacro, ServerError, bidirectional_protocol::SubCallback,
    process::ProcMacroServerProcess,
};

#[derive(Debug)]
pub(crate) struct ProcMacroServerPool {
    workers: Vec<Arc<ProcMacroServerProcess>>,
}

impl ProcMacroServerPool {
    pub(crate) fn new(workers: Vec<Arc<ProcMacroServerProcess>>) -> Self {
        Self { workers }
    }
}

impl ProcMacroServerPool {
    pub(crate) fn exited(&self) -> Option<&ServerError> {
        for worker in &self.workers {
            if let Some(e) = worker.exited() {
                return Some(e);
            }
        }
        None
    }

    pub(crate) fn load_dylib(
        &self,
        dylib: &MacroDylib,
        _callback: Option<SubCallback<'_>>,
    ) -> Result<Vec<ProcMacro>, ServerError> {
        let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered();
        let mut all_macros = Vec::new();

        for worker in &self.workers {
            let dylib_path = Arc::new(dylib.path.clone());
            let dylib_last_modified = std::fs::metadata(dylib_path.as_path())
                .ok()
                .and_then(|metadata| metadata.modified().ok());
            let macros = worker.load_dylib(&dylib.path, None)?;

            for (name, kind) in macros {
                all_macros.push(ProcMacro {
                    process: worker.clone(),
                    name: name.into(),
                    kind,
                    dylib_path: Arc::new(dylib.path.clone()),
                    dylib_last_modified,
                });
            }
        }

        Ok(all_macros)
    }
}

pub(crate) fn default_pool_size() -> usize {
    std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1).min(4)
}