use alloc::vec;
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::sync::Mutex;
#[cfg(feature = "std")]
use std::sync::MutexGuard;
#[cfg(not(feature = "std"))]
use iceoryx2_pal_concurrency_sync::spin_lock::SpinLock as Mutex;
#[cfg(not(feature = "std"))]
use iceoryx2_pal_concurrency_sync::spin_lock::SpinLockGuard as MutexGuard;
static CREATION_COUNTER: Mutex<usize> = Mutex::new(0);
static DROP_COUNTER: Mutex<usize> = Mutex::new(0);
static DROP_ORDER: Mutex<Vec<usize>> = Mutex::new(vec![]);
static TRACKING_LOCK: Mutex<LifetimeTrackingState> = Mutex::new(LifetimeTrackingState {});
#[derive(Debug)]
pub struct LifetimeTrackingState {}
impl LifetimeTrackingState {
pub fn number_of_living_instances(&self) -> usize {
*CREATION_COUNTER.lock().unwrap_or_else(|e| e.into_inner())
- *DROP_COUNTER.lock().unwrap_or_else(|e| e.into_inner())
}
pub fn drop_order(&self) -> Vec<usize> {
DROP_ORDER.lock().unwrap_or_else(|e| e.into_inner()).clone()
}
}
#[repr(C)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct LifetimeTracker {
pub value: usize,
}
impl Default for LifetimeTracker {
fn default() -> Self {
*CREATION_COUNTER.lock().unwrap_or_else(|e| e.into_inner()) += 1;
Self { value: 0 }
}
}
impl LifetimeTracker {
pub fn new() -> Self {
Self::default()
}
pub fn new_with_value(value: usize) -> Self {
let mut new_self = Self::new();
new_self.value = value;
new_self
}
pub fn start_tracking() -> MutexGuard<'static, LifetimeTrackingState> {
let guard = TRACKING_LOCK.lock().unwrap_or_else(|e| e.into_inner());
*CREATION_COUNTER.lock().unwrap_or_else(|e| e.into_inner()) = 0;
*DROP_COUNTER.lock().unwrap_or_else(|e| e.into_inner()) = 0;
DROP_ORDER.lock().unwrap_or_else(|e| e.into_inner()).clear();
guard
}
}
impl Clone for LifetimeTracker {
fn clone(&self) -> Self {
let mut new_self = Self::new();
new_self.value = self.value;
new_self
}
}
impl Drop for LifetimeTracker {
fn drop(&mut self) {
*DROP_COUNTER.lock().unwrap_or_else(|e| e.into_inner()) += 1;
DROP_ORDER
.lock()
.unwrap_or_else(|e| e.into_inner())
.push(self.value);
}
}