llm_agent_runtime/
util.rs1pub fn recover_lock<'a, T>(
8 result: std::sync::LockResult<std::sync::MutexGuard<'a, T>>,
9 ctx: &str,
10) -> std::sync::MutexGuard<'a, T>
11where
12 T: ?Sized,
13{
14 match result {
15 Ok(guard) => guard,
16 Err(poisoned) => {
17 tracing::warn!("mutex poisoned in {ctx}, recovering inner value");
18 poisoned.into_inner()
19 }
20 }
21}
22
23pub fn timed_lock<'a, T>(mutex: &'a std::sync::Mutex<T>, ctx: &str) -> std::sync::MutexGuard<'a, T>
28where
29 T: ?Sized,
30{
31 let start = std::time::Instant::now();
32 let result = mutex.lock();
33 let elapsed = start.elapsed();
34 if elapsed > std::time::Duration::from_millis(5) {
35 tracing::warn!(
36 duration_ms = elapsed.as_millis(),
37 ctx = ctx,
38 "slow mutex acquisition"
39 );
40 }
41 match result {
42 Ok(guard) => guard,
43 Err(poisoned) => {
44 tracing::warn!("mutex poisoned in {ctx}, recovering inner value");
45 poisoned.into_inner()
46 }
47 }
48}
49
50pub fn djb2(s: &str) -> u64 {
53 let mut h: u64 = 5381;
54 for b in s.bytes() {
55 h = h.wrapping_mul(33).wrapping_add(b as u64);
56 }
57 h
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_djb2_empty_string_returns_seed() {
66 assert_eq!(djb2(""), 5381);
67 }
68
69 #[test]
70 fn test_djb2_same_input_same_output() {
71 assert_eq!(djb2("hello"), djb2("hello"));
72 }
73
74 #[test]
75 fn test_djb2_different_inputs_differ() {
76 assert_ne!(djb2("foo"), djb2("bar"));
77 }
78
79 #[test]
80 fn test_djb2_known_value() {
81 assert_eq!(djb2("a"), 177670);
83 }
84
85 #[test]
88 fn test_recover_lock_returns_guard_for_healthy_mutex() {
89 use std::sync::Mutex;
90 let m = Mutex::new(42u32);
91 let guard = recover_lock(m.lock(), "test");
92 assert_eq!(*guard, 42);
93 }
94
95 #[test]
96 fn test_recover_lock_recovers_from_poisoned_mutex() {
97 use std::sync::{Arc, Mutex};
98 let m = Arc::new(Mutex::new(99u32));
99 let m2 = Arc::clone(&m);
100 let _ = std::thread::spawn(move || {
101 let _guard = m2.lock().unwrap();
102 panic!("intentional panic to poison mutex");
103 })
104 .join();
105 let guard = recover_lock(m.lock(), "poisoned test");
107 assert_eq!(*guard, 99);
108 }
109
110 #[test]
111 fn test_timed_lock_returns_guard_for_healthy_mutex() {
112 use std::sync::Mutex;
113 let m = Mutex::new("hello");
114 let guard = timed_lock(&m, "test");
115 assert_eq!(*guard, "hello");
116 }
117}