about summary refs log tree commit diff
path: root/library/std/src/sync
diff options
context:
space:
mode:
authorjoboet <jonasboettiger@icloud.com>2024-07-10 14:12:58 +0200
committerjoboet <jonasboettiger@icloud.com>2024-07-31 17:42:20 +0200
commitcf11f499b37e557e41f5eeac157c623d08e0068d (patch)
tree22b445f06b111e414e558268acd673dac613a5ff /library/std/src/sync
parent0b5eb7ba7bd796fb39c8bb6acd9ef6c140f28b65 (diff)
downloadrust-cf11f499b37e557e41f5eeac157c623d08e0068d.tar.gz
rust-cf11f499b37e557e41f5eeac157c623d08e0068d.zip
std: implement the `once_wait` feature
Diffstat (limited to 'library/std/src/sync')
-rw-r--r--library/std/src/sync/once.rs41
-rw-r--r--library/std/src/sync/once_lock.rs28
2 files changed, 69 insertions, 0 deletions
diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs
index 9d969af8c6d..17c56c85016 100644
--- a/library/std/src/sync/once.rs
+++ b/library/std/src/sync/once.rs
@@ -264,6 +264,47 @@ impl Once {
         self.inner.is_completed()
     }
 
+    /// Blocks the current thread until initialization has completed.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// #![feature(once_wait)]
+    ///
+    /// use std::sync::Once;
+    /// use std::thread;
+    ///
+    /// static READY: Once = Once::new();
+    ///
+    /// let thread = thread::spawn(|| {
+    ///     READY.wait();
+    ///     println!("everything is ready");
+    /// });
+    ///
+    /// READY.call_once(|| println!("performing setup"));
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// If this [`Once`] has been poisoned because an initialization closure has
+    /// panicked, this method will also panic. Use [`wait_force`](Self::wait_force)
+    /// if this behaviour is not desired.
+    #[unstable(feature = "once_wait", issue = "127527")]
+    pub fn wait(&self) {
+        if !self.inner.is_completed() {
+            self.inner.wait(false);
+        }
+    }
+
+    /// Blocks the current thread until initialization has completed, ignoring
+    /// poisoning.
+    #[unstable(feature = "once_wait", issue = "127527")]
+    pub fn wait_force(&self) {
+        if !self.inner.is_completed() {
+            self.inner.wait(true);
+        }
+    }
+
     /// Returns the current state of the `Once` instance.
     ///
     /// Since this takes a mutable reference, no initialization can currently
diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index 60e43a1cde1..efc1f415edf 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -167,6 +167,34 @@ impl<T> OnceLock<T> {
         }
     }
 
+    /// Blocks the current thread until the cell is initialized.
+    ///
+    /// # Example
+    ///
+    /// Waiting for a computation on another thread to finish:
+    /// ```rust
+    /// #![feature(once_wait)]
+    ///
+    /// use std::thread;
+    /// use std::sync::OnceLock;
+    ///
+    /// let value = OnceLock::new();
+    ///
+    /// thread::scope(|s| {
+    ///     s.spawn(|| value.set(1 + 1));
+    ///
+    ///     let result = value.wait();
+    ///     assert_eq!(result, &2);
+    /// })
+    /// ```
+    #[inline]
+    #[unstable(feature = "once_wait", issue = "127527")]
+    pub fn wait(&self) -> &T {
+        self.once.wait_force();
+
+        unsafe { self.get_unchecked() }
+    }
+
     /// Sets the contents of this cell to `value`.
     ///
     /// May block if another thread is currently attempting to initialize the cell. The cell is