Remove macOS sleep loop in favour of using `Condvar`
This solution was originally posted by @HybridEidolon in #185. Sorry it took so long! I thought it might be easier to open a new PR as half of your implementation here has already been implemented in a following PR (namely, the change from an unnecessary `Vec` of callbacks to a single user callback). Closes #185.
This commit is contained in:
parent
7e413cb660
commit
3603cbaee7
|
@ -28,7 +28,7 @@ use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::ptr::null;
|
use std::ptr::null;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Condvar, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
@ -434,6 +434,7 @@ pub struct EventLoop {
|
||||||
// stream to avoid streams blocking one another.
|
// stream to avoid streams blocking one another.
|
||||||
user_callback: Arc<Mutex<UserCallback>>,
|
user_callback: Arc<Mutex<UserCallback>>,
|
||||||
streams: Mutex<Vec<Option<StreamInner>>>,
|
streams: Mutex<Vec<Option<StreamInner>>>,
|
||||||
|
loop_cond: Arc<(Mutex<bool>, Condvar)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum UserCallback {
|
enum UserCallback {
|
||||||
|
@ -548,6 +549,7 @@ impl EventLoop {
|
||||||
EventLoop {
|
EventLoop {
|
||||||
user_callback: Arc::new(Mutex::new(UserCallback::Inactive)),
|
user_callback: Arc::new(Mutex::new(UserCallback::Inactive)),
|
||||||
streams: Mutex::new(Vec::new()),
|
streams: Mutex::new(Vec::new()),
|
||||||
|
loop_cond: Arc::new((Mutex::new(false), Condvar::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,11 +566,16 @@ impl EventLoop {
|
||||||
*guard = UserCallback::Active(unsafe { mem::transmute(callback) });
|
*guard = UserCallback::Active(unsafe { mem::transmute(callback) });
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
// Wait on a condvar to notify, which should never happen.
|
||||||
// So the loop does not get optimised out in --release
|
let &(ref lock, ref cvar) = &*self.loop_cond;
|
||||||
thread::sleep(Duration::new(1u64, 0u32));
|
let mut running = lock.lock().unwrap();
|
||||||
|
*running = true;
|
||||||
|
while *running {
|
||||||
|
running = cvar.wait(running).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unreachable!("current `EventLoop` API requires that `run` may not return");
|
||||||
|
|
||||||
// It is critical that we remove the callback before returning (currently not possible).
|
// It is critical that we remove the callback before returning (currently not possible).
|
||||||
// *self.user_callback.lock().unwrap() = UserCallback::Inactive;
|
// *self.user_callback.lock().unwrap() = UserCallback::Inactive;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue