#![cfg(feature = "stpool")]
use std::cell::RefCell;
use threadcell::{Guard as STPoolGuard, ThreadCell};
use crate::*;
pub struct STPool<T: Sized>(ThreadCell<RefCell<PoolInner<T>>>);
impl<T> STPool<T> {
#[inline]
#[must_use]
pub const fn new() -> Self {
Self(ThreadCell::new_disowned(RefCell::new(PoolInner::new())))
}
pub fn acquire(&self) -> Result<(), PoolOwnershipError> {
if self.0.try_acquire() {
Ok(())
} else {
Err(PoolOwnershipError)
}
}
pub fn release(&self) -> Result<(), PoolOwnershipError> {
if self.0.try_release() {
Ok(())
} else {
Err(PoolOwnershipError)
}
}
#[must_use = "the returned guard holds the threads ownership of the pool"]
pub fn acquire_guard(&self) -> Result<STPoolGuard<RefCell<PoolInner<T>>>, PoolOwnershipError> {
let guard = STPoolGuard::new(&self.0);
if guard.inner().try_acquire() {
Ok(guard)
} else {
Err(PoolOwnershipError)
}
}
pub unsafe fn force_release(&self) {
self.0.steal().release();
}
}
impl<T> PoolApi<T> for STPool<T> {}
impl<T> PoolLock<T> for &STPool<T> {
#[inline]
fn with_lock<R, F: FnOnce(&mut PoolInner<T>) -> R>(self, f: F) -> R {
f(&mut self.0.get().borrow_mut())
}
}
impl<T> Default for STPool<T> {
fn default() -> Self {
Self::new()
}
}