diff options
author | gennyble <gen@nyble.dev> | 2025-04-02 12:36:48 -0500 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2025-04-02 12:36:48 -0500 |
commit | ff02aba40dd599373380631a1d0e87ecbed3f8b5 (patch) | |
tree | 41aa5ca73fbf59b72f6ee92a7d33c7b76f9c7db4 | |
parent | 10925e207a28635e207459c5b78581385c9dbe9e (diff) | |
download | corgi-ff02aba40dd599373380631a1d0e87ecbed3f8b5.tar.gz corgi-ff02aba40dd599373380631a1d0e87ecbed3f8b5.zip |
mutex on modules so only one request can be handled at a time
-rw-r--r-- | corgi/src/caller.rs | 15 | ||||
-rw-r--r-- | corgi/src/main.rs | 4 |
2 files changed, 18 insertions, 1 deletions
diff --git a/corgi/src/caller.rs b/corgi/src/caller.rs index aef6bc3..7014d22 100644 --- a/corgi/src/caller.rs +++ b/corgi/src/caller.rs @@ -213,6 +213,20 @@ unsafe fn module_thread(script: Script, req: HttpRequest, tx: Sender<CgiResponse body: None, }; + // Since we can only load a dynamic library once, block other requests so + // they do not return the same handle. per dlopen docs: + // > If the same shared object is opened again with dlopen(), + // > the same object handle is returned. + let lock = match script.module_lock.lock() { + Ok(lock) => lock, + Err(poison) => { + eprintln!("!!! mutex for {} was poisoned!", script.name); + + // get the guard + poison.into_inner() + } + }; + unsafe { let lib = libloading::Library::new(script.filename).unwrap(); let handle: libloading::Symbol<HandleFn> = lib.get(b"cgi_handle").unwrap(); @@ -240,5 +254,6 @@ unsafe fn module_thread(script: Script, req: HttpRequest, tx: Sender<CgiResponse free(response); }; + drop(lock); tx.send(cgi).unwrap() } diff --git a/corgi/src/main.rs b/corgi/src/main.rs index fb6915b..3923084 100644 --- a/corgi/src/main.rs +++ b/corgi/src/main.rs @@ -2,7 +2,7 @@ use std::{ net::{IpAddr, SocketAddr}, path::PathBuf, pin::Pin, - sync::Arc, + sync::{Arc, Mutex}, time::Instant, }; @@ -40,6 +40,7 @@ pub enum ScriptKind { pub struct Script { name: String, kind: ScriptKind, + module_lock: Arc<Mutex<()>>, regex: Option<Regex>, filename: String, env: Vec<(String, String)>, @@ -107,6 +108,7 @@ fn parse_script_conf(conf: &Value) -> Script { Script { name, kind, + module_lock: Arc::new(Mutex::new(())), regex, filename, env: env.unwrap_or_default(), |