Incorperate feedback on Lazy helpers (#60)

This commit is contained in:
Joseph Richey 2019-07-11 13:21:45 -07:00 committed by Artyom Pavlov
parent 65660e00be
commit 9e0d7c7c68
2 changed files with 15 additions and 3 deletions

View File

@ -53,7 +53,8 @@ impl LazyUsize {
// Synchronously runs the init() function. Only one caller will have their
// init() function running at a time, and exactly one successful call will
// be run. The init() function should never return LazyUsize::ACTIVE.
// be run. init() returning UNINIT or ACTIVE will be considered a failure,
// and future calls to sync_init will rerun their init() function.
pub fn sync_init(&self, init: impl FnOnce() -> usize, mut wait: impl FnMut()) -> usize {
// Common and fast path with no contention. Don't wast time on CAS.
match self.0.load(Relaxed) {
@ -65,7 +66,13 @@ impl LazyUsize {
match self.0.compare_and_swap(Self::UNINIT, Self::ACTIVE, Relaxed) {
Self::UNINIT => {
let val = init();
self.0.store(val, Relaxed);
self.0.store(
match val {
Self::UNINIT | Self::ACTIVE => Self::UNINIT,
val => val,
},
Relaxed,
);
return val;
}
Self::ACTIVE => wait(),

View File

@ -80,7 +80,12 @@ impl LazyFd {
None => LazyUsize::UNINIT,
},
|| unsafe {
libc::usleep(1000);
// We are usually waiting on an open(2) syscall to complete,
// which typically takes < 10us if the file is a device.
// However, we might end up waiting much longer if the entropy
// pool isn't initialized, but even in that case, this loop will
// consume a negligible amount of CPU on most platforms.
libc::usleep(10);
},
);
match fd {