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

read-write-mutexify

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

read-write-mutexify - npm Package Compare versions

Comparing version 1.0.0 to 2.0.0

132

index.js

@@ -1,60 +0,120 @@

module.exports = class ReadWriteLock {
constructor () {
this.destroyed = false
class WriteLock {
constructor (parent) {
this.writing = false
this.readers = 0
this.waitingReads = []
this.waitingWrites = []
this._waiting = []
this._parent = parent
this._wait = pushToQueue.bind(this, this._waiting)
}
this._waitForWriteLockBound = pushToQueue.bind(this, this.waitingWrites)
this._waitForReadLockBound = pushToQueue.bind(this, this.waitingReads)
this._releaseWriteLockBound = this._releaseWriteLock.bind(this)
this._releaseReadLockBound = this._releaseReadLock.bind(this)
get locked () {
return this.writing || this._parent.read.readers > 0
}
write () {
if (this.writing === false && this.readers === 0) {
lock () {
if (this._parent._destroying) {
return Promise.reject(this._parent._destroyError)
}
if (this.writing === false && this._parent.read.readers === 0) {
this.writing = true
return Promise.resolve(this._releaseWriteLockBound)
return Promise.resolve()
}
return new Promise(this._waitForWriteLockBound)
return new Promise(this._wait)
}
read () {
if (this.writing === false) {
this.readers++
return Promise.resolve(this._releaseReadLockBound)
unlock () {
this.writing = false
this._parent._bump()
}
async flush () {
if (this.writing === false) return
try {
await this.lock()
} catch {
return
}
this.unlock()
}
}
return new Promise(this._waitForReadLockBound)
class ReadLock {
constructor (parent) {
this.readers = 0
this._waiting = []
this._parent = parent
this._wait = pushToQueue.bind(this, this._waiting)
}
destroy () {
if (this.destroyed) return
this.destroyed = true
while (this.waitingReads.length) this.waitingReads.shift()[1](new Error('Lock destroyed'))
while (this.waitingWrites.length) this.waitingWrites.shift()[1](new Error('Lock destroyed'))
get locked () {
return this._parent.writing
}
_releaseWriteLock () {
this.writing = false
this._bump()
lock () {
if (this._parent._destroying) {
return Promise.reject(this._parent._destroyError)
}
if (this._parent.write.writing === false) {
this.readers++
return Promise.resolve()
}
return new Promise(this._wait)
}
_releaseReadLock () {
unlock () {
this.readers--
this._bump()
this._parent._bump()
}
async flush () {
if (this.writing === false) return
try {
await this.lock()
} catch {
return
}
this.unlock()
}
}
module.exports = class ReadWriteLock {
constructor () {
this.read = new ReadLock(this)
this.write = new WriteLock(this)
this._destroyError = null
this._destroying = null
}
get destroyed () {
return !!this._destroying
}
destroy (err) {
if (this._destroying) return this._destroying
this._destroying = Promise.all([this.read.flush(), this.write.flush()])
this._destroyError = err || new Error('Mutex has been destroyed')
if (err) {
while (this.read._waiting) this._waiting.shift()[1](err)
while (this.write._waiting) this._waiting.shift()[1](err)
}
return this._destroying
}
_bump () {
if (this.writing === false && this.readers === 0 && this.waitingWrites.length > 0) {
this.writing = true
this.waitingWrites.shift()[0](this._releaseWriteLockBound)
if (this.write.writing === false && this.read.readers === 0 && this.write._waiting.length > 0) {
this.write.writing = true
this.write._waiting.shift()[0]()
}
while (this.writing === false && this.waitingReads.length > 0) {
this.readers++
this.waitingReads.shift()[0](this._releaseReadLockBound)
while (this.write.writing === false && this.read._waiting.length > 0) {
this.read.readers++
this.read._waiting.shift()[0]()
}

@@ -61,0 +121,0 @@ }

{
"name": "read-write-mutexify",
"version": "1.0.0",
"version": "2.0.0",
"description": "Like mutexify but with read/write locks",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -14,12 +14,19 @@ # read-write-mutexify

const lock = new RW()
const rw = new RW()
// read locks waits for writer locks to be released
const release1 = await lock.read()
const release2 = await lock.read() // make as many as you want
await rw.read.lock()
await rw.read.lock() // make as many as you want
// unlock with unlock
rw.read.unlock()
rw.read.unlock()
// only one writer can have the write lock and it waits
// for any read lock to be released
const release = await lock.writer()
await rw.write.lock()
// unlock with unlock
rw.write.unlock()
```

@@ -26,0 +33,0 @@

@@ -5,11 +5,11 @@ const test = require('brittle')

test('as many reads as you want', async function (t) {
const lock = new RW()
const rw = new RW()
const r1 = await lock.read()
const r2 = await lock.read()
await rw.read.lock()
await rw.read.lock()
t.pass('didnt dead lock')
r1()
r2()
rw.read.unlock()
rw.read.unlock()
})

@@ -20,8 +20,8 @@

const lock = new RW()
const rw = new RW()
let released = false
const release = await lock.write()
await rw.write.lock()
lock.write().then(() => {
rw.write.lock().then(() => {
t.ok(released, 'only one writer active')

@@ -32,3 +32,3 @@ })

release()
rw.write.unlock()
released = true

@@ -40,8 +40,8 @@ })

const lock = new RW()
const rw = new RW()
let released = false
const release = await lock.write()
await rw.write.lock()
lock.read().then(() => {
rw.read.lock().then(() => {
t.ok(released, 'read waited for writer')

@@ -52,3 +52,3 @@ })

release()
rw.write.unlock()
released = true

@@ -60,9 +60,9 @@ })

const lock = new RW()
const rw = new RW()
let released = false
const r1 = await lock.read()
const r2 = await lock.read()
await rw.read.lock()
await rw.read.lock()
lock.write().then(() => {
rw.write.lock().then(() => {
t.ok(released, 'write waited for all readers')

@@ -73,8 +73,8 @@ })

r1()
rw.read.unlock()
await new Promise(resolve => setImmediate(resolve))
r2()
rw.read.unlock()
released = true
})
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