pub use libc;
pub use lock_api;
#[macro_export]
macro_rules! static_system_mutex {
($name:ident) => {
static mut STATIC_PTHREAD_MUTEX: ::talc::sync::unix::libc::pthread_mutex_t =
::talc::sync::unix::libc::PTHREAD_MUTEX_INITIALIZER;
pub struct $name;
unsafe impl ::talc::sync::unix::lock_api::RawMutex for $name {
const INIT: Self = Self;
type GuardMarker = ::talc::sync::unix::lock_api::GuardSend;
#[inline]
fn lock(&self) {
unsafe {
::talc::sync::unix::libc::pthread_mutex_lock(core::ptr::addr_of_mut!(
STATIC_PTHREAD_MUTEX
));
}
}
#[inline]
fn try_lock(&self) -> bool {
unsafe {
::talc::sync::unix::libc::pthread_mutex_trylock(core::ptr::addr_of_mut!(
STATIC_PTHREAD_MUTEX
)) == 0
}
}
#[inline]
unsafe fn unlock(&self) {
unsafe {
::talc::sync::unix::libc::pthread_mutex_unlock(core::ptr::addr_of_mut!(
STATIC_PTHREAD_MUTEX
));
}
}
}
impl $name {
pub fn enable_child_alloc_after_fork() {
static FORK_PROTECTED: core::sync::atomic::AtomicUsize =
core::sync::atomic::AtomicUsize::new(0);
unsafe extern "C" fn _lock_mutex() {
::talc::sync::unix::libc::pthread_mutex_lock(core::ptr::addr_of_mut!(
STATIC_PTHREAD_MUTEX
));
}
unsafe extern "C" fn _unlock_mutex() {
::talc::sync::unix::libc::pthread_mutex_unlock(core::ptr::addr_of_mut!(
STATIC_PTHREAD_MUTEX
));
}
let cmpxchg_result = FORK_PROTECTED.compare_exchange(
0,
1,
core::sync::atomic::Ordering::Acquire,
core::sync::atomic::Ordering::Relaxed,
);
if cmpxchg_result.is_ok() {
let result = unsafe {
::talc::sync::unix::libc::pthread_atfork(
Some(_lock_mutex),
Some(_unlock_mutex),
Some(_unlock_mutex),
)
};
debug_assert_eq!(result, 0);
}
}
}
};
}