Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@matrixai/async-locks

Package Overview
Dependencies
Maintainers
4
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@matrixai/async-locks - npm Package Compare versions

Comparing version 2.2.5 to 2.3.0

2

dist/LockBox.d.ts

@@ -8,3 +8,3 @@ import type { ResourceAcquire } from '@matrixai/resources';

get count(): number;
isLocked(key?: ToString): boolean;
isLocked(key?: ToString, ...params: Parameters<L['isLocked']>): boolean;
waitForUnlock(timeout?: number, key?: ToString): Promise<void>;

@@ -11,0 +11,0 @@ withF<T>(...params: [

@@ -81,6 +81,6 @@ "use strict";

}
isLocked(key) {
isLocked(key, ...params) {
if (key == null) {
for (const lock of this._locks.values()) {
if (lock.isLocked())
if (lock.isLocked(...params))
return true;

@@ -94,3 +94,3 @@ }

return false;
return lock.isLocked();
return lock.isLocked(...params);
}

@@ -97,0 +97,0 @@ }

@@ -9,6 +9,9 @@ import type { MutexInterface } from 'async-mutex';

declare class RWLockReader implements Lockable {
protected readersLock: Mutex;
protected writersLock: Mutex;
protected writersRelease: MutexInterface.Releaser;
protected readerCountBlocked: number;
protected _readerCount: number;
protected _writerCount: number;
protected _lock: Mutex;
protected release: MutexInterface.Releaser;
protected activeLock: 'read' | 'write' | null;
lock(type: 'read' | 'write', timeout?: number): ResourceAcquire<RWLockReader>;

@@ -20,3 +23,7 @@ read(timeout?: number): ResourceAcquire<RWLockReader>;

get writerCount(): number;
isLocked(): boolean;
/**
* Check if locked
* If passed `type`, it will also check that the active lock is of that type
*/
isLocked(type?: 'read' | 'write'): boolean;
waitForUnlock(timeout?: number): Promise<void>;

@@ -23,0 +30,0 @@ withF<T>(...params: [

@@ -12,5 +12,8 @@ "use strict";

constructor() {
this.readersLock = new async_mutex_1.Mutex();
this.writersLock = new async_mutex_1.Mutex();
this.readerCountBlocked = 0;
this._readerCount = 0;
this._writerCount = 0;
this._lock = new async_mutex_1.Mutex();
this.activeLock = null;
}

@@ -27,18 +30,39 @@ lock(type, timeout) {

return async () => {
const t1 = performance.now();
++this.readerCountBlocked;
let readersLock = this.readersLock;
if (timeout != null) {
readersLock = (0, async_mutex_1.withTimeout)(this.readersLock, timeout, new errors_1.ErrorAsyncLocksTimeout());
}
let readersRelease;
try {
readersRelease = await readersLock.acquire();
}
catch (e) {
--this.readerCountBlocked;
throw e;
}
--this.readerCountBlocked;
const readerCount = ++this._readerCount;
// The first reader locks
if (readerCount === 1) {
let lock = this._lock;
let writersLock = this.writersLock;
if (timeout != null) {
lock = (0, async_mutex_1.withTimeout)(this._lock, timeout, new errors_1.ErrorAsyncLocksTimeout());
timeout = timeout - (performance.now() - t1);
writersLock = (0, async_mutex_1.withTimeout)(this.writersLock, timeout, new errors_1.ErrorAsyncLocksTimeout());
}
try {
this.release = await lock.acquire();
this.writersRelease = await writersLock.acquire();
}
catch (e) {
readersRelease();
--this._readerCount;
throw e;
}
readersRelease();
this.activeLock = 'read';
}
else {
readersRelease();
this.activeLock = 'read';
// Yield for the first reader to finish locking

@@ -49,7 +73,10 @@ await (0, utils_1.yieldMicro)();

async () => {
readersRelease = await this.readersLock.acquire();
const readerCount = --this._readerCount;
// The last reader unlocks
if (readerCount === 0) {
this.release();
this.writersRelease();
}
readersRelease();
this.activeLock = null;
// Allow semaphore to settle https://github.com/DirtyHairy/async-mutex/issues/54

@@ -65,9 +92,9 @@ await (0, utils_1.yieldMicro)();

++this._writerCount;
let lock = this._lock;
let writersLock = this.writersLock;
if (timeout != null) {
lock = (0, async_mutex_1.withTimeout)(this._lock, timeout, new errors_1.ErrorAsyncLocksTimeout());
writersLock = (0, async_mutex_1.withTimeout)(this.writersLock, timeout, new errors_1.ErrorAsyncLocksTimeout());
}
let release;
try {
release = await lock.acquire();
release = await writersLock.acquire();
}

@@ -78,2 +105,3 @@ catch (e) {

}
this.activeLock = 'write';
return [

@@ -83,2 +111,3 @@ async () => {

--this._writerCount;
this.activeLock = null;
// Allow semaphore to settle https://github.com/DirtyHairy/async-mutex/issues/54

@@ -95,3 +124,3 @@ await (0, utils_1.yieldMicro)();

get readerCount() {
return this._readerCount;
return this._readerCount + this.readerCountBlocked;
}

@@ -101,4 +130,14 @@ get writerCount() {

}
isLocked() {
return this._lock.isLocked();
/**
* Check if locked
* If passed `type`, it will also check that the active lock is of that type
*/
isLocked(type) {
if (type != null) {
return (this.activeLock === type &&
(this.readersLock.isLocked() || this.writersLock.isLocked()));
}
else {
return this.readersLock.isLocked() || this.writersLock.isLocked();
}
}

@@ -109,3 +148,6 @@ async waitForUnlock(timeout) {

await Promise.race([
this._lock.waitForUnlock(),
Promise.all([
this.readersLock.waitForUnlock(),
this.writersLock.waitForUnlock(),
]),
(0, utils_1.sleep)(timeout).then(() => {

@@ -120,3 +162,6 @@ timedOut = true;

else {
await this._lock.waitForUnlock();
await Promise.all([
this.readersLock.waitForUnlock(),
this.writersLock.waitForUnlock(),
]);
}

@@ -123,0 +168,0 @@ }

@@ -15,2 +15,3 @@ import type { MutexInterface } from 'async-mutex';

protected _writerCount: number;
protected activeLock: 'read' | 'write' | null;
lock(type: 'read' | 'write', timeout?: number): ResourceAcquire<RWLockWriter>;

@@ -22,3 +23,7 @@ read(timeout?: number): ResourceAcquire<RWLockWriter>;

get writerCount(): number;
isLocked(): boolean;
/**
* Check if locked
* If passed `type`, it will also check that the active lock is of that type
*/
isLocked(type?: 'read' | 'write'): boolean;
waitForUnlock(timeout?: number): Promise<void>;

@@ -25,0 +30,0 @@ withF<T>(...params: [

@@ -18,2 +18,3 @@ "use strict";

this._writerCount = 0;
this.activeLock = null;
}

@@ -66,4 +67,6 @@ lock(type, timeout) {

}
this.activeLock = 'read';
}
else {
this.activeLock = 'read';
// Yield for the first reader to finish locking

@@ -78,2 +81,3 @@ await (0, utils_1.yieldMicro)();

this.readersRelease();
this.activeLock = null;
// Allow semaphore to settle https://github.com/DirtyHairy/async-mutex/issues/54

@@ -118,2 +122,3 @@ await (0, utils_1.yieldMicro)();

}
this.activeLock = 'write';
return [

@@ -124,2 +129,3 @@ async () => {

--this._writerCount;
this.activeLock = null;
// Allow semaphore to settle https://github.com/DirtyHairy/async-mutex/issues/54

@@ -141,4 +147,14 @@ await (0, utils_1.yieldMicro)();

}
isLocked() {
return this.readersLock.isLocked() || this.writersLock.isLocked();
/**
* Check if locked
* If passed `type`, it will also check that the active lock is of that type
*/
isLocked(type) {
if (type != null) {
return (this.activeLock === type &&
(this.readersLock.isLocked() || this.writersLock.isLocked()));
}
else {
return this.readersLock.isLocked() || this.writersLock.isLocked();
}
}

@@ -145,0 +161,0 @@ async waitForUnlock(timeout) {

@@ -17,3 +17,3 @@ import type { ResourceAcquire } from '@matrixai/resources';

lock(...params: Array<unknown>): ResourceAcquire<Lockable>;
isLocked(): boolean;
isLocked(...params: Array<unknown>): boolean;
waitForUnlock(timeout?: number): Promise<void>;

@@ -20,0 +20,0 @@ withF<T>(...params: Array<unknown>): Promise<T>;

{
"name": "@matrixai/async-locks",
"version": "2.2.5",
"version": "2.3.0",
"author": "Roger Qiu",

@@ -15,3 +15,4 @@ "description": "Asynchronous locking utilities",

"prepare": "tsc -p ./tsconfig.build.json",
"build": "rm -r ./dist || true; tsc -p ./tsconfig.build.json",
"build": "rimraf ./dist && tsc -p ./tsconfig.build.json",
"postversion": "npm install --package-lock-only --ignore-scripts --silent",
"ts-node": "ts-node -r tsconfig-paths/register",

@@ -21,3 +22,3 @@ "test": "jest",

"lintfix": "eslint '{src,tests}/**/*.{js,ts}' --fix",
"docs": "rm -r ./docs || true; typedoc --gitRevision master --tsconfig ./tsconfig.build.json --out ./docs src"
"docs": "rimraf ./docs && typedoc --gitRevision master --tsconfig ./tsconfig.build.json --out ./docs src"
},

@@ -39,3 +40,5 @@ "dependencies": {

"jest": "^27.2.5",
"jest-junit": "^13.2.0",
"prettier": "^2.6.2",
"rimraf": "^3.0.2",
"ts-jest": "^27.0.5",

@@ -42,0 +45,0 @@ "ts-node": "^10.4.0",

# js-async-locks
[![pipeline status](https://gitlab.com/MatrixAI/open-source/js-async-locks/badges/master/pipeline.svg)](https://gitlab.com/MatrixAI/open-source/js-async-locks/commits/master)
staging:[![pipeline status](https://gitlab.com/MatrixAI/open-source/js-async-locks/badges/staging/pipeline.svg)](https://gitlab.com/MatrixAI/open-source/js-async-locks/commits/staging)
master:[![pipeline status](https://gitlab.com/MatrixAI/open-source/js-async-locks/badges/master/pipeline.svg)](https://gitlab.com/MatrixAI/open-source/js-async-locks/commits/master)

@@ -5,0 +6,0 @@ Asynchronous lock utilities.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc