Skip to main content

windjammer_runtime/
thread.rs

1//! Threading utilities
2//!
3//! Windjammer's thread module provides ergonomic thread spawning and management
4//! with simplified error handling.
5
6pub use std::thread::{
7    current, panicking, park, park_timeout, sleep, spawn, yield_now, Builder, JoinHandle, Thread,
8    ThreadId,
9};
10pub use std::time::Duration;
11
12/// Spawn a new thread with a closure
13pub fn spawn_thread<F, T>(f: F) -> JoinHandle<T>
14where
15    F: FnOnce() -> T + Send + 'static,
16    T: Send + 'static,
17{
18    spawn(f)
19}
20
21/// Sleep for a number of seconds
22pub fn sleep_seconds(secs: u64) {
23    sleep(Duration::from_secs(secs))
24}
25
26/// Sleep for a number of milliseconds
27pub fn sleep_millis(millis: u64) {
28    sleep(Duration::from_millis(millis))
29}
30
31/// Sleep for a number of microseconds
32pub fn sleep_micros(micros: u64) {
33    sleep(Duration::from_micros(micros))
34}
35
36/// Get the current thread
37pub fn current_thread() -> Thread {
38    current()
39}
40
41/// Get the current thread ID
42pub fn current_id() -> ThreadId {
43    current().id()
44}
45
46/// Get the current thread name
47pub fn current_name() -> Option<String> {
48    current().name().map(String::from)
49}
50
51/// Yield the current thread
52pub fn yield_thread() {
53    yield_now()
54}
55
56/// Check if the current thread is panicking
57pub fn is_panicking() -> bool {
58    panicking()
59}
60
61/// Park the current thread
62pub fn park_thread() {
63    park()
64}
65
66/// Park the current thread with timeout
67pub fn park_thread_timeout(duration: Duration) {
68    park_timeout(duration)
69}
70
71/// Join a thread and unwrap the result
72pub fn join<T>(handle: JoinHandle<T>) -> T {
73    handle.join().expect("Thread panicked")
74}
75
76/// Try to join a thread
77pub fn try_join<T>(handle: JoinHandle<T>) -> Result<T, String> {
78    handle.join().map_err(|_| "Thread panicked".to_string())
79}
80
81/// Get available parallelism (number of logical cores)
82pub fn available_parallelism() -> usize {
83    std::thread::available_parallelism()
84        .map(|n| n.get())
85        .unwrap_or(1)
86}
87
88/// Scope-based thread spawning (safe scoped threads)
89pub fn scope<'env, F, R>(f: F) -> R
90where
91    F: for<'scope> FnOnce(&'scope std::thread::Scope<'scope, 'env>) -> R,
92{
93    std::thread::scope(f)
94}
95
96#[cfg(test)]
97mod tests {
98    use super::*;
99
100    #[test]
101    fn test_spawn_and_join() {
102        let handle = spawn_thread(|| 42);
103
104        assert_eq!(join(handle), 42);
105    }
106
107    #[test]
108    fn test_sleep() {
109        let start = std::time::Instant::now();
110        sleep_millis(100);
111        let elapsed = start.elapsed();
112
113        assert!(elapsed.as_millis() >= 100);
114    }
115
116    #[test]
117    fn test_current_thread() {
118        let thread = current_thread();
119        let id = current_id();
120
121        assert_eq!(thread.id(), id);
122    }
123
124    #[test]
125    fn test_available_parallelism() {
126        let n = available_parallelism();
127        assert!(n >= 1);
128    }
129
130    #[test]
131    fn test_scoped_threads() {
132        let mut data = [1, 2, 3, 4];
133
134        scope(|s| {
135            s.spawn(|| {
136                data[0] = 10;
137            });
138        });
139
140        assert_eq!(data[0], 10);
141    }
142}