From 610e575043bfc75feafcce5bddaf7e1a436e5d02 Mon Sep 17 00:00:00 2001 From: Mica White Date: Sun, 7 Dec 2025 14:23:22 -0500 Subject: First commit --- src/processes.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/processes.rs (limited to 'src/processes.rs') diff --git a/src/processes.rs b/src/processes.rs new file mode 100644 index 0000000..7ac326f --- /dev/null +++ b/src/processes.rs @@ -0,0 +1,78 @@ +use std::collections::HashMap; +use std::sync::{LazyLock, RwLock, mpsc}; +use std::thread::JoinHandle; + +use happylock::ThreadKey; +use uuid::Uuid; + +use crate::pipe::{Message, MessageResponse}; + +thread_local! { + static PROCESS_ID: RwLock = const { RwLock::new(Uuid::nil()) }; +} + +static RUNNING_PROCESSES: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); + +#[derive(Debug)] +pub struct Process { + id: Uuid, + thread: JoinHandle<()>, + channel: mpsc::Sender, +} + +pub fn is_builtin(program_id: Uuid) -> bool { + program_id.as_u64_pair().0 == 0 +} + +pub fn process_id(key: &mut ThreadKey) -> Uuid { + PROCESS_ID.with(|id| *id.read().unwrap()) +} + +pub fn send_message(key: &mut ThreadKey, program_id: Uuid, message: Message) -> MessageResponse { + start_program(key, program_id); + + let programs = RUNNING_PROCESSES.read().unwrap(); + // TODO: this can crash if the program runs and exits immediately + let program = programs.get(&program_id).unwrap(); + + let response = MessageResponse::from_message(&message); + _ = program.channel.send(message); + response +} + +pub fn start_builtin_as(key: &mut ThreadKey, package_id: Uuid, as_program: Uuid) -> Option<()> { + let mut processes = RUNNING_PROCESSES.write().unwrap(); + if processes.contains_key(&as_program) { + return Some(()); + } + + let builtin_index = package_id.as_u64_pair().1 as usize; + let func = crate::builtins::BUILTINS.get(builtin_index)?.as_ref()?; + let (sender, receiver) = mpsc::channel(); + let handle = std::thread::spawn(move || { + let key = ThreadKey::get().expect("the thread just started"); + PROCESS_ID.with(|id| { + *id.write().unwrap() = as_program; + }); + func(key, receiver); + }); + let process = Process { + id: as_program, + thread: handle, + channel: sender, + }; + processes.insert(as_program, process); + + Some(()) +} + +pub fn start_builtin(key: &mut ThreadKey, package_id: Uuid) -> Option<()> { + start_builtin_as(key, package_id, package_id) +} + +pub fn start_program(key: &mut ThreadKey, package_id: Uuid) -> Option<()> { + start_builtin(key, package_id)?; + + Some(()) +} -- cgit v1.2.3