use std::sync::{
Arc, Mutex,
atomic::{AtomicBool, Ordering},
};
use log::warn;
use super::output::Output;
use crate::connection::information_packet::Content;
#[derive(Debug)]
pub(crate) struct ExecState {
success: AtomicBool,
output: Arc<Mutex<Output>>,
}
impl ExecState {
pub(crate) fn new() -> Self {
Self {
success: AtomicBool::new(false),
output: Arc::new(Mutex::new(Output::empty())),
}
}
pub(crate) fn set_output(&self, output: Output) {
self.success.store(true, Ordering::Relaxed);
match self.output.lock() {
Ok(mut guard) => {
*guard = output;
}
Err(poisoned) => {
warn!("ExecState output mutex poisoned in set_output, recovering inner value");
*poisoned.into_inner() = output;
}
}
}
pub(crate) fn get_output(&self) -> Option<Content> {
match self.output.lock() {
Ok(guard) => guard.get_out(),
Err(poisoned) => {
warn!("ExecState output mutex poisoned in get_output, recovering inner value");
poisoned.into_inner().get_out()
}
}
}
pub(crate) fn get_full_output(&self) -> Output {
match self.output.lock() {
Ok(guard) => guard.clone(),
Err(poisoned) => {
warn!("ExecState output mutex poisoned in get_full_output, recovering inner value");
poisoned.into_inner().clone()
}
}
}
pub(crate) fn exe_success(&self) {
self.success.store(true, Ordering::Relaxed)
}
pub(crate) fn exe_fail(&self) {
self.success.store(false, Ordering::Relaxed)
}
pub(crate) fn is_success(&self) -> bool {
self.success.load(Ordering::Relaxed)
}
}