#![cfg(all(target_arch = "wasm32", feature = "opfs"))]
#![allow(unsafe_code)]
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
#[derive(Clone, Copy)]
enum LockKind {
Exclusive,
Shared,
}
#[derive(Default)]
pub(super) struct LockMap {
entries: HashMap<String, (LockKind, u32)>,
}
impl LockMap {
pub(super) fn try_exclusive(&mut self, path: &str) -> bool {
if self.entries.contains_key(path) {
return false;
}
self.entries
.insert(path.to_string(), (LockKind::Exclusive, 1));
true
}
pub(super) fn try_shared(&mut self, path: &str) -> bool {
match self.entries.get_mut(path) {
None => {
self.entries.insert(path.to_string(), (LockKind::Shared, 1));
true
}
Some((LockKind::Shared, n)) => {
*n += 1;
true
}
Some((LockKind::Exclusive, _)) => false,
}
}
pub(super) fn release(&mut self, path: &str) {
let remove = match self.entries.get_mut(path) {
Some((_, n)) if *n <= 1 => true,
Some((_, n)) => {
*n -= 1;
false
}
None => false,
};
if remove {
self.entries.remove(path);
}
}
}
pub struct OpfsLockHandle {
pub(super) path: String,
pub(super) locks: Arc<Mutex<LockMap>>,
}
unsafe impl Send for OpfsLockHandle {}
unsafe impl Sync for OpfsLockHandle {}
impl Drop for OpfsLockHandle {
fn drop(&mut self) {
if let Ok(mut map) = self.locks.lock() {
map.release(&self.path);
}
}
}