pub(crate) use init_once::InitOnce;
mod init_once;
use crate::SemaphoreRef;
use core::{ffi::c_uint,
fmt,
fmt::{Display, Formatter},
hint,
pin::Pin};
#[allow(private_bounds)]
pub trait Semaphore: Default + Sync + Sealed {
fn init_with(self: Pin<&Self>, sem_count: c_uint) -> Result<SemaphoreRef<'_>, bool>;
fn sem_ref(self: Pin<&Self>) -> Result<SemaphoreRef<'_>, ()>;
#[inline]
fn init(self: Pin<&Self>) -> Result<SemaphoreRef<'_>, bool> { self.init_with(0) }
#[must_use]
#[inline]
fn try_init(self: Pin<&Self>, limit: u64) -> Option<SemaphoreRef<'_>> {
self.try_init_with(limit, 0)
}
#[must_use]
#[inline]
fn try_init_with(
self: Pin<&Self>,
mut limit: u64,
sem_count: c_uint,
) -> Option<SemaphoreRef<'_>> {
match self.init_with(sem_count) {
Ok(sem_ref) => Some(sem_ref),
Err(true) => loop {
if let Ok(sem_ref) = self.sem_ref() {
break Some(sem_ref); }
limit = limit.saturating_sub(1);
if limit == 0 {
break None; }
hint::spin_loop();
},
Err(false) => None, }
}
#[must_use]
#[inline]
fn display(self: Pin<&Self>) -> impl Display + '_ { Displayer(self) }
}
struct Displayer<T>(T);
impl<T: Semaphore> Display for Displayer<Pin<&T>> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self.0.sem_ref() {
Ok(sem) => <SemaphoreRef<'_> as Display>::fmt(&sem, f),
Err(()) => write!(f, "<Semaphore>"),
}
}
}
pub(crate) trait Sealed {}