use kithara_platform::{
sync::Mutex,
thread::{self, Thread},
};
#[derive(Default)]
pub(crate) struct ThreadWake {
waiter: Mutex<Option<Thread>>,
}
impl ThreadWake {
pub(crate) fn register_current(&self) {
*self.waiter.lock_sync() = Some(thread::current());
}
}
impl crate::runtime::WakeSignal for ThreadWake {
fn wake(&self) {
let waiter = self.waiter.lock_sync().as_ref().cloned();
if let Some(waiter) = waiter {
waiter.unpark();
}
}
}
#[cfg(test)]
mod tests {
use std::{
sync::{
Arc,
atomic::{AtomicBool, Ordering},
},
time::Duration,
};
use kithara_platform::thread::{park_timeout, sleep, spawn};
use kithara_test_utils::kithara;
use super::ThreadWake;
use crate::runtime::WakeSignal;
#[kithara::test]
fn wake_unparks_registered_thread() {
#[cfg(not(target_arch = "wasm32"))]
{
let wake = Arc::new(ThreadWake::default());
let done = Arc::new(AtomicBool::new(false));
let worker_wake = Arc::clone(&wake);
let worker_done = Arc::clone(&done);
let join = spawn(move || {
worker_wake.register_current();
park_timeout(Duration::from_secs(1));
worker_done.store(true, Ordering::Release);
});
sleep(Duration::from_millis(10));
wake.wake();
join.join().expect("wake test thread");
assert!(done.load(Ordering::Acquire));
}
}
}