use crate::{arena, base, huge, prof, tcache};
use core::sync::atomic::{AtomicBool, Ordering};
pub(crate) fn register() {
static DONE: AtomicBool = AtomicBool::new(false);
if DONE.swap(true, Ordering::Relaxed) {
return;
}
unsafe {
libc::pthread_atfork(Some(prepare), Some(parent), Some(child));
}
}
unsafe extern "C" fn prepare() {
arena::fork_lock();
huge::fork_lock();
prof::fork_lock();
tcache::fork_lock();
base::fork_lock();
}
unsafe fn unlock_all() {
unsafe {
base::fork_unlock();
tcache::fork_unlock();
prof::fork_unlock();
huge::fork_unlock();
arena::fork_unlock();
}
}
unsafe extern "C" fn parent() {
unsafe { unlock_all() };
}
unsafe extern "C" fn child() {
unsafe {
unlock_all();
let t = tcache::current();
arena::fork_child(if t.is_null() {
core::ptr::null_mut()
} else {
(*t).arena
});
}
crate::background::fork_child();
}