use std::sync::atomic::{AtomicU8, Ordering};
#[cfg(any(feature = "async-rt", feature = "multi-rt", feature = "local-rt"))]
use jl_sys::jl_is_initialized;
pub(crate) const GC_UNSAFE: i8 = 0;
#[repr(u8)]
#[derive(PartialEq, Debug)]
pub enum State {
Uninit,
Init,
PendingExit,
Exit,
StartedFromJulia,
}
static JULIA_STATE: AtomicU8 = AtomicU8::new(State::Uninit as u8);
pub unsafe fn set_started_from_julia() -> bool {
JULIA_STATE
.compare_exchange(
State::Uninit as u8,
State::StartedFromJulia as u8,
Ordering::Relaxed,
Ordering::Relaxed,
)
.is_ok()
}
pub fn current_state() -> State {
unsafe { std::mem::transmute(JULIA_STATE.load(Ordering::Relaxed)) }
}
pub fn current_state_is(state: State) -> bool {
current_state() == state
}
pub fn is_init() -> bool {
current_state_is(State::Init)
}
#[cfg(any(feature = "async-rt", feature = "multi-rt", feature = "local-rt"))]
pub(super) fn can_init() -> bool {
unsafe {
if jl_is_initialized() != 0 {
return false;
}
}
try_set_init()
}
#[cfg(any(feature = "async-rt", feature = "multi-rt", feature = "local-rt"))]
pub(super) unsafe fn set_exit() {
JULIA_STATE.store(State::Exit as _, Ordering::Relaxed);
}
#[cfg(feature = "multi-rt")]
pub(super) unsafe fn set_pending_exit() {
JULIA_STATE.store(State::PendingExit as _, Ordering::Relaxed);
}
#[cfg(any(feature = "async-rt", feature = "multi-rt", feature = "local-rt"))]
fn try_set_init() -> bool {
JULIA_STATE
.compare_exchange(
State::Uninit as _,
State::Init as _,
Ordering::Relaxed,
Ordering::Relaxed,
)
.is_ok()
}