Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc-macro-api/src/pool.rs')
-rw-r--r--crates/proc-macro-api/src/pool.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/crates/proc-macro-api/src/pool.rs b/crates/proc-macro-api/src/pool.rs
new file mode 100644
index 0000000000..685bc05be6
--- /dev/null
+++ b/crates/proc-macro-api/src/pool.rs
@@ -0,0 +1,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)
+}