From b4605f90ba9a64ccf893c7e2a583f4265dc2a5d1 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Tue, 1 Aug 2023 21:16:58 +1000 Subject: [PATCH] sync: Add const fn `OnceCell::from_value` Signed-off-by: Jiahao XU --- tokio/src/sync/batch_semaphore.rs | 14 ++++++++++++++ tokio/src/sync/once_cell.rs | 32 +++++++++++++++++++++++++++++++ tokio/src/sync/semaphore.rs | 10 ++++++++++ 3 files changed, 56 insertions(+) diff --git a/tokio/src/sync/batch_semaphore.rs b/tokio/src/sync/batch_semaphore.rs index e0dafaa256e..d848b803656 100644 --- a/tokio/src/sync/batch_semaphore.rs +++ b/tokio/src/sync/batch_semaphore.rs @@ -206,6 +206,20 @@ impl Semaphore { } } + /// Creates a new closed semaphore with 0 permits. + #[cfg(not(all(loom, test)))] + pub(crate) const fn const_new_closed() -> Self { + Self { + permits: AtomicUsize::new(Self::CLOSED), + waiters: Mutex::const_new(Waitlist { + queue: LinkedList::new(), + closed: true, + }), + #[cfg(all(tokio_unstable, feature = "tracing"))] + resource_span: tracing::Span::none(), + } + } + /// Returns the current number of available permits. pub(crate) fn available_permits(&self) -> usize { self.permits.load(Acquire) >> Self::PERMIT_SHIFT diff --git a/tokio/src/sync/once_cell.rs b/tokio/src/sync/once_cell.rs index 8a5463a3be7..1128bcfd81f 100644 --- a/tokio/src/sync/once_cell.rs +++ b/tokio/src/sync/once_cell.rs @@ -149,6 +149,38 @@ impl OnceCell { } } + /// Creates a new `OnceCell` that contains the provided value. + /// + /// This is equivalent to ` as From>::from(value)`. + /// + /// # Example + /// + /// ``` + /// use tokio::sync::OnceCell; + /// + /// static ONCE: OnceCell = OnceCell::from_value(1); + /// + /// async fn get_global_integer() -> &'static u32 { + /// ONCE.get_or_init(|| async { + /// 1 + 1 + /// }).await + /// } + /// + /// #[tokio::main] + /// async fn main() { + /// let result = get_global_integer().await; + /// assert_eq!(*result, 1); + /// } + /// ``` + #[cfg(not(all(loom, test)))] + pub const fn from_value(value: T) -> Self { + OnceCell { + value_set: AtomicBool::new(true), + value: UnsafeCell::new(MaybeUninit::new(value)), + semaphore: Semaphore::const_new_closed(), + } + } + /// Creates a new empty `OnceCell` instance. /// /// Equivalent to `OnceCell::new`, except that it can be used in static diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index cb770215488..96506bf17cc 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -190,6 +190,16 @@ impl Semaphore { } } + /// Creates a new closed semaphore with 0 permits. + #[cfg(not(all(loom, test)))] + pub(crate) const fn const_new_closed() -> Self { + Self { + ll_sem: ll::Semaphore::const_new_closed(), + #[cfg(all(tokio_unstable, feature = "tracing"))] + resource_span: tracing::Span::none(), + } + } + /// Returns the current number of available permits. pub fn available_permits(&self) -> usize { self.ll_sem.available_permits()