summaryrefslogtreecommitdiff
path: root/src/processes.rs
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2025-12-07 14:23:22 -0500
committerMica White <botahamec@outlook.com>2025-12-07 14:23:22 -0500
commit610e575043bfc75feafcce5bddaf7e1a436e5d02 (patch)
tree15149b937984f73feb7bb63be662882094f27abe /src/processes.rs
First commitHEADmain
Diffstat (limited to 'src/processes.rs')
-rw-r--r--src/processes.rs78
1 files changed, 78 insertions, 0 deletions
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<Uuid> = const { RwLock::new(Uuid::nil()) };
+}
+
+static RUNNING_PROCESSES: LazyLock<RwLock<HashMap<Uuid, Process>>> =
+ LazyLock::new(|| RwLock::new(HashMap::new()));
+
+#[derive(Debug)]
+pub struct Process {
+ id: Uuid,
+ thread: JoinHandle<()>,
+ channel: mpsc::Sender<Message>,
+}
+
+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(())
+}