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..178d29bfecd 100644 --- a/tokio/src/sync/once_cell.rs +++ b/tokio/src/sync/once_cell.rs @@ -149,6 +149,36 @@ impl OnceCell { } } + /// Creates a new `OnceCell` that contains the provided value. + /// + /// # Example + /// + /// ``` + /// use tokio::sync::OnceCell; + /// + /// static ONCE: OnceCell = OnceCell::const_new_with(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 const_new_with(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 30936762ddb..348134a9062 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -219,6 +219,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()