use std::{collections::VecDeque, sync::LazyLock};
use parking_lot::{Condvar, Mutex};
pub struct TaskQueue {
condvar: Condvar,
queue: LazyLock<Mutex<VecDeque<Box<dyn FnOnce() + Send + 'static>>>>,
}
impl TaskQueue {
pub const fn new() -> Self {
Self {
condvar: Condvar::new(),
queue: LazyLock::new(|| Mutex::new(VecDeque::new())),
}
}
pub fn push<F: FnOnce() + Send + 'static>(&self, function: F) {
let mut queue = self.queue.lock();
queue.push_back(Box::new(function));
self.condvar.notify_one();
}
pub fn pop(&self) -> Box<dyn FnOnce() + Send + 'static> {
let mut queue = self.queue.lock();
loop {
match queue.pop_front() {
Some(f) => return f,
None => self.condvar.wait(&mut queue),
}
}
}
}
unsafe impl Send for TaskQueue {}
unsafe impl Sync for TaskQueue {}