| Crates.io | cross-locks |
| lib.rs | cross-locks |
| version | 0.1.3 |
| created_at | 2025-05-21 16:52:25.96096+00 |
| updated_at | 2025-05-29 10:32:35.364164+00 |
| description | FIFO-fair global locks that work identically on native, browser-WASM and head-less WASM. |
| homepage | |
| repository | |
| max_upload_size | |
| id | 1683641 |
| size | 134,566 |
cross-locks provides a single-file, zero-dependency¹ implementation of named, FIFO, re-entrant global locks that Just Work everywhere – native back-ends, WASM in the browser, and single-threaded test binaries – with identical APIs and semantics.
¹ Apart from the optional runtime adapters (tokio, wasm-bindgen) and the tiny derive helpers async-trait /
thiserror.
Navigator.locks) or on the server
without extra feature flags in your application code.Arc<T> auto-impl – store the lock directly in shared state (e.g. Axum Extension).# Cargo.toml
[dependencies]
cross-locks = { version = "0.1", default-features = false, features = ["native"] } # or "browser"
tokio = { version = "1", optional = true, features = ["sync", "rt-multi-thread"] }
use cross_locks::{GlobalLock, DefaultLock};
use std::time::Duration;
#[tokio::main]
async fn main() {
let lock = DefaultLock::default();
lock.with_lock("auth.cs", Duration::from_secs(1), || async {
// … critical section …
}).await.unwrap();
}
| Target | --features |
Crate size | Guarantees |
|---|---|---|---|
| Native (Tokio multi-thread) | native |
tiny | FIFO, timeout, re-entry |
| Browser WASM (2022+) | browser |
tiny | Delegates to Navigator.locks |
| Tests / single-thread CLI | (none) | tiny | No-op passthrough |
Safari ≥ 16.4, Chrome ≥ 69, Firefox ≥ 94 already ship the Web Locks API.
GlobalLock is an async-trait with a blanket impl for Arc<T>, so you can plug in bespoke back-ends (e.g. a Postgres
advisory lock):
struct PgLock {
pool: sqlx::PgPool
}
#[async_trait::async_trait]
impl GlobalLock for PgLock {
async fn with_lock<R, F, Fut>(
&self, name: &str, timeout: Duration, op: F
) -> Result<R, cross_locks::LockError>
where
F: FnOnce() -> Fut + Send + 'static,
Fut: std::future::Future<Output=R> + Send + 'static,
R: Send + 'static,
{
// acquire advisory lock, run op, release …
}
}
# exhaustive suite on native
cargo test --features native
# smoke-test in headless Firefox
wasm-pack test --firefox --headless --features browser
The repository ships a tiny dual_test! macro so you can write once, run everywhere:
cross_locks::dual_test! { arc_inner_reentrancy {
/* body compiled as a Tokio test natively and as a wasm_bindgen_test in browsers */
}}
Licensed under either 🅰 Apache-2.0 or 🅱 MIT at your option – see LICENSE-* for details.
Inspired by Supabase’s JS SDK and the GoTrue service; thanks to the Web Locks API editors for a sane browser primitive.
Happy hacking & safe locking! — @geoffreygarrett