Skip to content

Commit

Permalink
Handle spurious wakeups in wait_timeout_sgx
Browse files Browse the repository at this point in the history
  • Loading branch information
mzohreva committed Jun 12, 2020
1 parent c4b0265 commit d7dc64b
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 6 deletions.
16 changes: 12 additions & 4 deletions src/libstd/sys/sgx/mod.rs
Expand Up @@ -115,9 +115,15 @@ pub fn decode_error_kind(code: i32) -> ErrorKind {
// timeouts in SGX model. The enclave runner serving usercalls may lie about
// current time and/or ignore timeout values.
//
// Once the event is observed, `stop` will be used to determine whether or not
// we should continue to wait.
//
// FIXME: note these caveats in documentation of all public types that use this
// function in their execution path.
pub fn wait_timeout_sgx(event_mask: u64, duration: crate::time::Duration) {
pub fn wait_timeout_sgx<F>(event_mask: u64, duration: crate::time::Duration, stop: F)
where
F: Fn() -> bool,
{
use self::abi::usercalls;
use crate::cmp;
use crate::io::ErrorKind;
Expand All @@ -129,11 +135,13 @@ pub fn wait_timeout_sgx(event_mask: u64, duration: crate::time::Duration) {
let timeout = cmp::min((u64::MAX - 1) as u128, remaining.as_nanos()) as u64;
match usercalls::wait(event_mask, timeout) {
Ok(eventset) => {
if event_mask != 0 {
rtassert!(eventset & event_mask == event_mask);
if event_mask == 0 {
rtabort!("expected usercalls::wait() to return Err, found Ok.");
}
rtassert!(eventset & event_mask == event_mask);
if stop() {
return;
}
rtabort!("expected usercalls::wait() to return Err, found Ok.");
}
Err(e) => {
rtassert!(e.kind() == ErrorKind::TimedOut || e.kind() == ErrorKind::WouldBlock)
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/sgx/thread.rs
Expand Up @@ -76,7 +76,7 @@ impl Thread {
}

pub fn sleep(dur: Duration) {
wait_timeout_sgx(0, dur);
wait_timeout_sgx(0, dur, || true);
}

pub fn join(self) {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/sgx/waitqueue.rs
Expand Up @@ -177,7 +177,7 @@ impl WaitQueue {
let entry_lock = lock.lock().queue.inner.push(&mut entry);
before_wait();
// don't panic, this would invalidate `entry` during unwinding
wait_timeout_sgx(EV_UNPARK, timeout);
wait_timeout_sgx(EV_UNPARK, timeout, || entry_lock.lock().wake);
// acquire the wait queue's lock first to avoid deadlock.
let mut guard = lock.lock();
let entry_guard = entry_lock.lock();
Expand Down

0 comments on commit d7dc64b

Please sign in to comment.