Commit 48f64dce authored by Ralf's avatar Ralf
Browse files

implement waking up a thread

parent 9058fa27
// While we are still prototyping, allow dead code
// FIXME: While we are still prototyping, allow dead code
#![allow(dead_code)]
#[macro_use]
......
use std::time::Duration;
use std::sync;
use std::sync::{Arc, Mutex, Condvar};
use std::thread;
#[derive(PartialEq,Eq,Debug,Copy,Clone)]
pub enum ShouldThreadRun {
Yes,
No,
}
pub struct Wakeable<T> {
join: thread::JoinHandle<T>,
state: Arc<ThreadState>,
}
pub struct Thread {
state: Arc<ThreadState>,
}
struct ThreadState {
mutex: Mutex<ShouldThreadRun>,
cond: Condvar,
}
pub struct Thread;
impl<T: Send + 'static> Wakeable<T> {
pub fn new<F>(f: F) -> Self
where F: FnOnce(Thread) -> T + Send + 'static
{
Wakeable { join: thread::spawn(|| f(Thread)) }
let state = Arc::new(ThreadState {
mutex: Mutex::new(ShouldThreadRun::Yes),
cond: Condvar::new(),
});
let thread = Thread { state: state.clone() };
Wakeable {
join: thread::spawn(move || f(thread)),
state: state,
}
}
pub fn terminate(self) -> T {
{
// We panic if the lock is poisened, which only happens if someone paniced
let mut should_run = self.state.mutex.lock().unwrap();
*should_run = ShouldThreadRun::No;
self.state.cond.notify_one();
}
self.join.join().unwrap() // If the child thread paniced, so do we
}
}
impl Thread {
pub fn sleep(&self, _: Duration) -> sync::WaitTimeoutResult {
unimplemented!()
pub fn sleep(&self, d: Duration) -> ShouldThreadRun {
// We panic if the lock is poisened, which only happens if someone paniced
let should_run = self.state.mutex.lock().unwrap();
// check if we have to terminate early
if *should_run == ShouldThreadRun::No {
return ShouldThreadRun::No;
}
// We panic if the lock is poisened, which only happens if someone paniced
let (should_run, _) = self.state.cond.wait_timeout(should_run, d).unwrap();
return *should_run;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment