#![allow(unsafe_code)]
use core::ffi::c_void;
use crate::hton::{HaPanicFunction, HaStatType, StatPrintSink};
use crate::panic_guard::FfiBoundary;
use crate::runtime;
use crate::runtime::FfiPtr;
use crate::sys;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__panic(flag: u32) -> i32 {
FfiBoundary::run(|| match runtime::handlerton() {
Some(h) => h.panic(HaPanicFunction::from_raw(flag)),
None => Ok(()),
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__start_consistent_snapshot(thd: *const sys::THD) -> i32 {
FfiBoundary::run(|| {
let thd = unsafe { thd.as_ref() };
match runtime::handlerton() {
Some(h) => h.start_consistent_snapshot(thd),
None => Ok(()),
}
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__flush_logs(binlog_group_flush: bool) -> bool {
FfiBoundary::run_default(false, || match runtime::handlerton() {
Some(h) => match h.flush_logs(binlog_group_flush) {
Ok(()) => false,
Err(_) => true,
},
None => false,
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__show_status(
thd: *const sys::THD,
print_fn: *const c_void,
stat: u32,
) -> bool {
FfiBoundary::run_default(false, || {
let thd_ref = unsafe { thd.as_ref() };
let sink = StatPrintSink::new(thd_ref, print_fn);
match runtime::handlerton() {
Some(h) => match h.show_status(thd_ref, &sink, HaStatType::from_raw(stat)) {
Ok(()) => false,
Err(_) => true,
},
None => false,
}
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__partition_flags() -> u32 {
FfiBoundary::run_default(0, || match runtime::handlerton() {
Some(h) => h.partition_flags(),
None => 0,
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__fill_is_table(thd: *const sys::THD) -> i32 {
FfiBoundary::run(|| {
let thd = unsafe { thd.as_ref() };
match runtime::handlerton() {
Some(h) => h.fill_is_table(thd),
None => Ok(()),
}
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__upgrade_logs(thd: *const sys::THD) -> i32 {
FfiBoundary::run(|| {
let thd = unsafe { thd.as_ref() };
match runtime::handlerton() {
Some(h) => h.upgrade_logs(thd),
None => Ok(()),
}
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__finish_upgrade(
thd: *const sys::THD,
failed_upgrade: bool,
) -> i32 {
FfiBoundary::run(|| {
let thd = unsafe { thd.as_ref() };
match runtime::handlerton() {
Some(h) => h.finish_upgrade(thd, failed_upgrade),
None => Ok(()),
}
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__hton__is_reserved_db_name(name: *const u8, name_len: usize) -> bool {
FfiBoundary::run_default(false, || {
let decoded = unsafe { FfiPtr::bytes_to_str(name, name_len) };
match decoded {
Ok(s) => match runtime::handlerton() {
Some(h) => h.is_reserved_db_name(s),
None => false,
},
Err(_) => false,
}
})
}
#[cfg(test)]
mod tests {
use crate::hton::{HaPanicFunction, HaStatType};
#[test]
fn panic_function_from_raw_round_trip() {
assert_eq!(HaPanicFunction::from_raw(0), HaPanicFunction::Close);
assert_eq!(HaPanicFunction::from_raw(1), HaPanicFunction::Write);
}
#[test]
fn stat_type_from_raw_round_trip() {
assert_eq!(HaStatType::from_raw(0), HaStatType::Status);
assert_eq!(HaStatType::from_raw(2), HaStatType::Mutex);
}
}