Offload functions to worker threads with shared memory primitives for Node.js.
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(shared): add RwLock.tryReadLock synchronous variant

+46
+13
src/shared/rwlock.ts
··· 63 63 } 64 64 } 65 65 66 + /** 67 + * Attempts to acquire a read lock without waiting. 68 + * Makes a single atomic attempt; returns `null` on contention even from other readers. 69 + * @returns A disposable {@link ReadGuard} if acquired, otherwise `null`. 70 + */ 71 + tryReadLock(): ReadGuard | null { 72 + const state = Atomics.load(this.view, 0); 73 + if (state >= UNLOCKED && Atomics.compareExchange(this.view, 0, state, state + 1) === state) { 74 + return new ReadGuard(this); 75 + } 76 + return null; 77 + } 78 + 66 79 /** Releases a read lock. Wakes a waiting writer if this was the last reader. */ 67 80 readUnlock(): void { 68 81 const prev = Atomics.sub(this.view, 0, 1);
+33
test/shared/rwlock.test.ts
··· 118 118 const results = await Promise.all([reader1Done, reader2Done]); 119 119 assert.deepEqual(results.sort(), ['r1', 'r2']); 120 120 }); 121 + 122 + it('tryReadLock returns a guard when unlocked', () => { 123 + const rw = rwlock(); 124 + const guard = rw.tryReadLock(); 125 + assert.ok(guard); 126 + assert.equal(typeof guard[Symbol.dispose], 'function'); 127 + guard[Symbol.dispose](); 128 + // Should be able to read-lock again after dispose 129 + const guard2 = rw.tryReadLock(); 130 + assert.ok(guard2); 131 + rw.readUnlock(); 132 + }); 133 + 134 + it('multiple concurrent tryReadLock calls all succeed', () => { 135 + const rw = rwlock(); 136 + const g1 = rw.tryReadLock(); 137 + const g2 = rw.tryReadLock(); 138 + const g3 = rw.tryReadLock(); 139 + assert.ok(g1); 140 + assert.ok(g2); 141 + assert.ok(g3); 142 + rw.readUnlock(); 143 + rw.readUnlock(); 144 + rw.readUnlock(); 145 + }); 146 + 147 + it('tryReadLock returns null when write-locked', async () => { 148 + const rw = rwlock(); 149 + await rw.writeLock(); 150 + const guard = rw.tryReadLock(); 151 + assert.equal(guard, null); 152 + rw.writeUnlock(); 153 + }); 121 154 });