use std::path::{Path, PathBuf};
use std::sync::{Condvar, Mutex};
#[derive(Debug, Default)]
pub(super) struct SyncGate {
paused: Mutex<bool>,
resumed: Condvar,
waiting: Mutex<Vec<PathBuf>>,
}
impl SyncGate {
pub(super) fn pause(&self) {
*self.paused.lock().expect("the gate") = true;
}
pub(super) fn resume(&self) {
*self.paused.lock().expect("the gate") = false;
self.resumed.notify_all();
}
pub(super) fn waiting(&self, prefix: &str) -> bool {
self.waiting.lock().expect("the list").iter().any(|path| {
path.file_name()
.is_some_and(|name| name.to_string_lossy().starts_with(prefix))
})
}
pub(super) fn pass(&self, path: &Path) {
let mut paused = self.paused.lock().expect("the gate");
if !*paused {
return;
}
self.waiting
.lock()
.expect("the list")
.push(path.to_path_buf());
while *paused {
paused = self.resumed.wait(paused).expect("the gate");
}
drop(paused);
let mut waiting = self.waiting.lock().expect("the list");
if let Some(index) = waiting.iter().position(|waiting| waiting == path) {
waiting.swap_remove(index);
}
}
}