Skip to content

Commit 9baab45

Browse files
committed
Aborting when before_wait function panics
1 parent 9a5443f commit 9baab45

File tree

1 file changed

+10
-6
lines changed
  • library/std/src/sys/sgx/waitqueue

1 file changed

+10
-6
lines changed

library/std/src/sys/sgx/waitqueue/mod.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod unsafe_list;
1818

1919
use crate::num::NonZeroUsize;
2020
use crate::ops::{Deref, DerefMut};
21+
use crate::panic::{self, AssertUnwindSafe};
2122
use crate::time::Duration;
2223

2324
use super::abi::thread;
@@ -147,9 +148,8 @@ impl WaitQueue {
147148
/// Adds the calling thread to the `WaitVariable`'s wait queue, then wait
148149
/// until a wakeup event.
149150
///
150-
/// This function does not return until this thread has been awoken.
151-
///
152-
/// Safety: `before_wait` must not panic
151+
/// This function does not return until this thread has been awoken. When `before_wait` panics,
152+
/// this function will abort.
153153
pub fn wait<T, F: FnOnce()>(mut guard: SpinMutexGuard<'_, WaitVariable<T>>, before_wait: F) {
154154
// very unsafe: check requirements of UnsafeList::push
155155
unsafe {
@@ -159,7 +159,9 @@ impl WaitQueue {
159159
}));
160160
let entry = guard.queue.inner.push(&mut entry);
161161
drop(guard);
162-
before_wait();
162+
if let Err(_e) = panic::catch_unwind(AssertUnwindSafe(|| before_wait())) {
163+
rtabort!("Panic before wait on wakeup event")
164+
}
163165
while !entry.lock().wake {
164166
// `entry.wake` is only set in `notify_one` and `notify_all` functions. Both ensure
165167
// the entry is removed from the queue _before_ setting this bool. There are no
@@ -174,7 +176,7 @@ impl WaitQueue {
174176
/// Adds the calling thread to the `WaitVariable`'s wait queue, then wait
175177
/// until a wakeup event or timeout. If event was observed, returns true.
176178
/// If not, it will remove the calling thread from the wait queue.
177-
/// Safety: `before_wait` must not panic
179+
/// When `before_wait` panics, this function will abort.
178180
pub fn wait_timeout<T, F: FnOnce()>(
179181
lock: &SpinMutex<WaitVariable<T>>,
180182
timeout: Duration,
@@ -187,7 +189,9 @@ impl WaitQueue {
187189
wake: false,
188190
}));
189191
let entry_lock = lock.lock().queue.inner.push(&mut entry);
190-
before_wait();
192+
if let Err(_e) = panic::catch_unwind(AssertUnwindSafe(|| before_wait())) {
193+
rtabort!("Panic before wait on wakeup event or timeout")
194+
}
191195
usercalls::wait_timeout(EV_UNPARK, timeout, || entry_lock.lock().wake);
192196
// acquire the wait queue's lock first to avoid deadlock
193197
// and ensure no other function can simultaneously access the list

0 commit comments

Comments
 (0)