use std::ffi::CString;
use std::os::raw::c_char;
use std::sync::Mutex;
use error::{Error, ErrorKind};
use state::ProfilerState;
use util::check_file_path;
lazy_static! {
#[derive(Debug)]
pub static ref PROFILER: Mutex<Profiler> = Mutex::new(Profiler {
state: ProfilerState::NotActive,
});
}
#[allow(non_snake_case)]
extern "C" {
fn ProfilerStart(fname: *const c_char) -> i32;
fn ProfilerStop();
}
#[derive(Debug)]
pub struct Profiler {
state: ProfilerState,
}
impl Profiler {
pub fn state(&self) -> ProfilerState {
self.state
}
pub fn start<T: Into<Vec<u8>>>(&mut self, fname: T) -> Result<(), Error> {
if self.state == ProfilerState::NotActive {
let c_fname = try!(CString::new(fname));
check_file_path(c_fname.clone().into_string().unwrap())?;
unsafe {
let res = ProfilerStart(c_fname.as_ptr());
if res == 0 {
Err(ErrorKind::InternalError.into())
} else {
self.state = ProfilerState::Active;
Ok(())
}
}
} else {
Err(ErrorKind::InvalidState(self.state).into())
}
}
pub fn stop(&mut self) -> Result<(), Error> {
if self.state == ProfilerState::Active {
unsafe {
ProfilerStop();
}
self.state = ProfilerState::NotActive;
Ok(())
} else {
Err(ErrorKind::InvalidState(self.state).into())
}
}
}