about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorRaoul Strackx <raoul.strackx@fortanix.com>2023-05-15 15:10:25 +0200
committerRaoul Strackx <raoul.strackx@fortanix.com>2023-07-31 12:59:42 +0200
commit9a5443fe21bfaba77a4c872ec76b8e828bb265c0 (patch)
tree17a413dd300624e7efeb0335fe60ebf8381765e1 /library/std/src
parent5082281609a7c3bcba0292b0db6a0d3e20bf9549 (diff)
downloadrust-9a5443fe21bfaba77a4c872ec76b8e828bb265c0.tar.gz
rust-9a5443fe21bfaba77a4c872ec76b8e828bb265c0.zip
`waitqueue` clarifications for SGX platform
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/sys/sgx/waitqueue/mod.rs16
1 files changed, 12 insertions, 4 deletions
diff --git a/library/std/src/sys/sgx/waitqueue/mod.rs b/library/std/src/sys/sgx/waitqueue/mod.rs
index 5e1d859ee99..32328123f73 100644
--- a/library/std/src/sys/sgx/waitqueue/mod.rs
+++ b/library/std/src/sys/sgx/waitqueue/mod.rs
@@ -148,6 +148,8 @@ impl WaitQueue {
     /// until a wakeup event.
     ///
     /// This function does not return until this thread has been awoken.
+    ///
+    /// Safety: `before_wait` must not panic
     pub fn wait<T, F: FnOnce()>(mut guard: SpinMutexGuard<'_, WaitVariable<T>>, before_wait: F) {
         // very unsafe: check requirements of UnsafeList::push
         unsafe {
@@ -159,6 +161,9 @@ impl WaitQueue {
             drop(guard);
             before_wait();
             while !entry.lock().wake {
+                // `entry.wake` is only set in `notify_one` and `notify_all` functions. Both ensure
+                // the entry is removed from the queue _before_ setting this bool. There are no
+                // other references to `entry`.
                 // don't panic, this would invalidate `entry` during unwinding
                 let eventset = rtunwrap!(Ok, usercalls::wait(EV_UNPARK, WAIT_INDEFINITE));
                 rtassert!(eventset & EV_UNPARK == EV_UNPARK);
@@ -169,6 +174,7 @@ impl WaitQueue {
     /// Adds the calling thread to the `WaitVariable`'s wait queue, then wait
     /// until a wakeup event or timeout. If event was observed, returns true.
     /// If not, it will remove the calling thread from the wait queue.
+    /// Safety: `before_wait` must not panic
     pub fn wait_timeout<T, F: FnOnce()>(
         lock: &SpinMutex<WaitVariable<T>>,
         timeout: Duration,
@@ -183,7 +189,9 @@ impl WaitQueue {
             let entry_lock = lock.lock().queue.inner.push(&mut entry);
             before_wait();
             usercalls::wait_timeout(EV_UNPARK, timeout, || entry_lock.lock().wake);
-            // acquire the wait queue's lock first to avoid deadlock.
+            // acquire the wait queue's lock first to avoid deadlock
+            // and ensure no other function can simultaneously access the list
+            // (e.g., `notify_one` or `notify_all`)
             let mut guard = lock.lock();
             let success = entry_lock.lock().wake;
             if !success {
@@ -204,8 +212,8 @@ impl WaitQueue {
     ) -> Result<WaitGuard<'_, T>, SpinMutexGuard<'_, WaitVariable<T>>> {
         // SAFETY: lifetime of the pop() return value is limited to the map
         // closure (The closure return value is 'static). The underlying
-        // stack frame won't be freed until after the WaitGuard created below
-        // is dropped.
+        // stack frame won't be freed until after the lock on the queue is released
+        // (i.e., `guard` is dropped).
         unsafe {
             let tcs = guard.queue.inner.pop().map(|entry| -> Tcs {
                 let mut entry_guard = entry.lock();
@@ -231,7 +239,7 @@ impl WaitQueue {
     ) -> Result<WaitGuard<'_, T>, SpinMutexGuard<'_, WaitVariable<T>>> {
         // SAFETY: lifetime of the pop() return values are limited to the
         // while loop body. The underlying stack frames won't be freed until
-        // after the WaitGuard created below is dropped.
+        // after the lock on the queue is released (i.e., `guard` is dropped).
         unsafe {
             let mut count = 0;
             while let Some(entry) = guard.queue.inner.pop() {