use crate::dynamic_non_blocking_mutex_task::DynamicNonBlockingMutexTask;
use crate::mutex_guard::MutexGuard;
use crate::non_blocking_mutex::NonBlockingMutex;
use crate::non_blocking_mutex_task::NonBlockingMutexTask;
use std::sync::atomic::Ordering;
pub type DynamicNonBlockingMutex<'captured_variables, State> = NonBlockingMutex<
'captured_variables,
State,
DynamicNonBlockingMutexTask<'captured_variables, State>,
>;
impl<'captured_variables, State> DynamicNonBlockingMutex<'captured_variables, State> {
pub fn run_fn_once_if_first_or_schedule_on_first(
&self,
run_with_state: impl FnOnce(MutexGuard<State>) + Send + 'captured_variables,
) {
if self.task_count.fetch_add(1, Ordering::Acquire) != 0 {
self.task_queue
.push_back(DynamicNonBlockingMutexTask::from_fn_once_impl(
run_with_state,
));
} else {
run_with_state(unsafe { MutexGuard::new(&self.unsafe_state) });
while self.task_count.fetch_sub(1, Ordering::Release) != 1 {
self.task_queue
.pop_front_or_spin_wait_item()
.run_with_state(unsafe { MutexGuard::new(&self.unsafe_state) });
}
}
}
}