Skip to content

Commit d7dc64b

Browse files
committed
Handle spurious wakeups in wait_timeout_sgx
1 parent c4b0265 commit d7dc64b

File tree

3 files changed

+14
-6
lines changed

3 files changed

+14
-6
lines changed

src/libstd/sys/sgx/mod.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,15 @@ pub fn decode_error_kind(code: i32) -> ErrorKind {
115115
// timeouts in SGX model. The enclave runner serving usercalls may lie about
116116
// current time and/or ignore timeout values.
117117
//
118+
// Once the event is observed, `stop` will be used to determine whether or not
119+
// we should continue to wait.
120+
//
118121
// FIXME: note these caveats in documentation of all public types that use this
119122
// function in their execution path.
120-
pub fn wait_timeout_sgx(event_mask: u64, duration: crate::time::Duration) {
123+
pub fn wait_timeout_sgx<F>(event_mask: u64, duration: crate::time::Duration, stop: F)
124+
where
125+
F: Fn() -> bool,
126+
{
121127
use self::abi::usercalls;
122128
use crate::cmp;
123129
use crate::io::ErrorKind;
@@ -129,11 +135,13 @@ pub fn wait_timeout_sgx(event_mask: u64, duration: crate::time::Duration) {
129135
let timeout = cmp::min((u64::MAX - 1) as u128, remaining.as_nanos()) as u64;
130136
match usercalls::wait(event_mask, timeout) {
131137
Ok(eventset) => {
132-
if event_mask != 0 {
133-
rtassert!(eventset & event_mask == event_mask);
138+
if event_mask == 0 {
139+
rtabort!("expected usercalls::wait() to return Err, found Ok.");
140+
}
141+
rtassert!(eventset & event_mask == event_mask);
142+
if stop() {
134143
return;
135144
}
136-
rtabort!("expected usercalls::wait() to return Err, found Ok.");
137145
}
138146
Err(e) => {
139147
rtassert!(e.kind() == ErrorKind::TimedOut || e.kind() == ErrorKind::WouldBlock)

src/libstd/sys/sgx/thread.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl Thread {
7676
}
7777

7878
pub fn sleep(dur: Duration) {
79-
wait_timeout_sgx(0, dur);
79+
wait_timeout_sgx(0, dur, || true);
8080
}
8181

8282
pub fn join(self) {

src/libstd/sys/sgx/waitqueue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl WaitQueue {
177177
let entry_lock = lock.lock().queue.inner.push(&mut entry);
178178
before_wait();
179179
// don't panic, this would invalidate `entry` during unwinding
180-
wait_timeout_sgx(EV_UNPARK, timeout);
180+
wait_timeout_sgx(EV_UNPARK, timeout, || entry_lock.lock().wake);
181181
// acquire the wait queue's lock first to avoid deadlock.
182182
let mut guard = lock.lock();
183183
let entry_guard = entry_lock.lock();

0 commit comments

Comments
 (0)