use async_lock::Mutex;
use std::future::Future;
use std::hint::spin_loop;
pub struct AQueue {
lock: Mutex<()>,
}
impl Default for AQueue {
#[inline]
fn default() -> Self {
AQueue { lock: Mutex::new(()) }
}
}
impl AQueue {
#[inline]
pub fn new() -> AQueue {
AQueue::default()
}
#[inline]
pub fn sync_run<A, R>(&self, call: impl FnOnce(A) -> R, arg: A) -> R {
loop {
let guard = self.lock.try_lock();
if guard.is_some() {
return call(arg);
} else {
spin_loop();
}
}
}
#[inline]
pub async fn run<A, T, R>(&self, call: impl FnOnce(A) -> T, arg: A) -> R
where
T: Future<Output = R>,
{
self.check_run(call(arg)).await
}
#[inline]
async fn check_run<R, T>(&self, future: T) -> R
where
T: Future<Output = R>,
{
let _guard = self.lock.lock().await;
future.await
}
}