use crate::{api, check, sys, Error, Result};
use std::ffi::CString;
use std::ptr;
use std::sync::Arc;
pub(crate) struct EnvInner {
env: *mut sys::EnvHandle,
threading: Option<crate::threading::ThreadingOptions>,
}
#[derive(Clone)]
pub struct Environment(Arc<EnvInner>);
impl Environment {
pub fn new() -> Result<Self> {
Self::new_with_level(sys::LoggingLevel::Warning, "zrt")
}
pub fn new_with_level(level: sys::LoggingLevel, logid: &str) -> Result<Self> {
let cid = CString::new(logid)
.map_err(|_| Error::new(-1, "environment log id contains a NUL byte"))?;
let mut env: *mut sys::EnvHandle = ptr::null_mut();
check(unsafe { api().create_env()(level, cid.as_ptr(), &mut env) })?;
let env = crate::ensure_non_null(env, "environment")?;
Ok(Self(Arc::new(EnvInner {
env,
threading: None,
})))
}
pub fn new_with_global_thread_pools(
level: sys::LoggingLevel, logid: &str, threading: crate::threading::ThreadingOptions,
) -> Result<Self> {
let cid = CString::new(logid)
.map_err(|_| Error::new(-1, "environment log id contains a NUL byte"))?;
let mut env: *mut sys::EnvHandle = ptr::null_mut();
check(unsafe {
api().create_env_with_global_thread_pools()(
level,
cid.as_ptr(),
threading.as_ptr(),
&mut env,
)
})?;
let env = crate::ensure_non_null(env, "environment")?;
Ok(Self(Arc::new(EnvInner {
env,
threading: Some(threading),
})))
}
#[inline]
pub(crate) fn as_ptr(&self) -> *const sys::EnvHandle {
(self.0).env as *const sys::EnvHandle
}
#[inline]
pub(crate) fn share(&self) -> Arc<EnvInner> {
self.0.clone()
}
#[inline]
pub(crate) fn has_global_thread_pool(&self) -> bool {
self.0.threading.is_some()
}
pub fn register_allocator(
&self, mem_info: &crate::memory::MemoryInfo, arena_cfg: &crate::arena::ArenaCfg,
) -> Result<()> {
check(unsafe {
api().create_and_register_allocator()(
(self.0).env,
mem_info.info as *const sys::MemoryInfoHandle,
arena_cfg.as_ptr(),
)
})
}
}
impl Drop for EnvInner {
fn drop(&mut self) {
unsafe { api().release_env()(self.env) }
}
}
unsafe impl Send for EnvInner {}
unsafe impl Sync for EnvInner {}