use std::{collections::VecDeque, sync::{Condvar, Mutex}};
pub enum QueueFlow<T>{
Value(T),
Unblock,
}
pub struct Queue<T> {
queue: Mutex<VecDeque<QueueFlow<T>>>,
condvar: Condvar
}
impl<T> Queue<T> {
pub fn with_capacity(size: usize) -> Self {
Queue {
queue: Mutex::new(VecDeque::with_capacity(size)),
condvar: Condvar::new()
}
}
pub fn push(&self, item: T) {
let mut queue = self.queue.lock().unwrap();
queue.push_back(QueueFlow::Value(item));
self.condvar.notify_one();
}
pub fn pop(&self) -> Option<T> {
let mut queue = self.queue.lock().unwrap();
loop {
match queue.pop_front(){
Some(QueueFlow::Value(v)) => return Some(v),
Some(QueueFlow::Unblock) => return None,
None => (),
}
queue = self.condvar.wait(queue).unwrap();
}
}
pub fn unblock(&self) {
let mut queue = self.queue.lock().unwrap();
queue.push_back(QueueFlow::Unblock);
self.condvar.notify_one();
}
}