From c9a1794a11cd1ff4b8c7df9592ca0411c1414d98 Mon Sep 17 00:00:00 2001 From: Devin Ivy Date: Thu, 23 Apr 2026 16:12:07 -0400 Subject: [PATCH] docs(shared): changeset + README for try* lock variants Co-Authored-By: Claude Opus 4.7 (1M context) --- .changeset/try-lock-variants.md | 23 +++++++++++++++++++++++ README.md | 8 ++++++++ 2 files changed, 31 insertions(+) create mode 100644 .changeset/try-lock-variants.md diff --git a/.changeset/try-lock-variants.md b/.changeset/try-lock-variants.md new file mode 100644 index 0000000..94f503d --- /dev/null +++ b/.changeset/try-lock-variants.md @@ -0,0 +1,23 @@ +--- +'moroutine': minor +--- + +Synchronous `try*` variants for shared locks + +**New methods on `Mutex` and `RwLock`**: + +```ts +// Non-blocking, single-attempt acquisition. +// Returns a disposable guard on success, `null` on contention. +mutex.tryLock(); // MutexGuard | null +rwlock.tryReadLock(); // ReadGuard | null +rwlock.tryWriteLock(); // WriteGuard | null +``` + +Each makes a single atomic CAS attempt — no waiting, no retry. Composes with `using` since `null` skips dispose registration: + +```ts +using guard = mu.tryLock(); +if (!guard) return; // held elsewhere, nothing to dispose +// ...critical section; auto-unlock on scope exit +``` diff --git a/README.md b/README.md index 5efb089..f34588a 100644 --- a/README.md +++ b/README.md @@ -310,6 +310,10 @@ using guard = await mu.lock(); // or manually: await mu.lock(); mu.unlock(); + +// Non-blocking attempt — returns null if held elsewhere. +using guard = mu.tryLock(); +if (!guard) return; ``` #### RwLock @@ -319,6 +323,10 @@ const rw = rwlock(); using guard = await rw.readLock(); // multiple readers OK using guard = await rw.writeLock(); // exclusive access + +// Non-blocking variants — return null if unavailable. +using r = rw.tryReadLock(); // null if write-locked +using w = rw.tryWriteLock(); // null if any lock is held ``` ### Using with Workers -- 2.51.2