use std::sync::atomic::{AtomicBool, Ordering};
use crate::{AWS_OP_SUCCESS, aws_log_level, aws_log_subject_t, aws_logger, aws_string};
pub type LogFn = unsafe extern "C" fn(
logger: *mut aws_logger,
log_level: aws_log_level::Type,
subject: aws_log_subject_t,
body: *mut aws_string,
body_length: usize,
) -> libc::c_int;
static LOGGER_LOG_FN_INIT: AtomicBool = AtomicBool::new(false);
static mut LOGGER_LOG_FN: Option<LogFn> = None;
pub fn try_init(f: LogFn) -> Result<(), LoggerInitError> {
if LOGGER_LOG_FN_INIT
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
.is_ok()
{
unsafe {
LOGGER_LOG_FN = Some(f);
}
Ok(())
} else {
Err(LoggerInitError::AlreadyInitialized)
}
}
#[derive(Debug, Clone, Copy)]
pub enum LoggerInitError {
AlreadyInitialized,
}
#[link(name = "logging_shim", kind = "static")]
unsafe extern "C" {
pub unsafe fn aws_crt_s3_rs_logging_shim_log_fn_trampoline(
logger: *mut aws_logger,
log_level: aws_log_level::Type,
subject: aws_log_subject_t,
format: *const libc::c_char,
...
) -> libc::c_int;
}
#[unsafe(no_mangle)]
unsafe extern "C" fn aws_crt_s3_rs_logging_shim_log_fn(
logger: *mut aws_logger,
log_level: aws_log_level::Type,
subject: aws_log_subject_t,
body: *mut aws_string,
body_length: usize,
) -> libc::c_int {
unsafe {
if let Some(f) = LOGGER_LOG_FN {
f(logger, log_level, subject, body, body_length)
} else {
AWS_OP_SUCCESS
}
}
}