50 lines
1.0 KiB
JavaScript
50 lines
1.0 KiB
JavaScript
const { EventEmitter, on } = require('events')
|
|
|
|
class Lock {
|
|
constructor () {
|
|
this._locked = false
|
|
this._emitter = new EventEmitter()
|
|
}
|
|
|
|
/**
|
|
* Synchronous. Returns true if the lock was acquired. Return false if the lock is already held by something else.
|
|
* @returns {boolean}
|
|
*/
|
|
tryAcquire () {
|
|
if (!this._locked) {
|
|
this._locked = true
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* Asynchronous. Resolves when the lock was acquired.
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async acquire () {
|
|
if (!this._locked) {
|
|
this._locked = true
|
|
return
|
|
}
|
|
|
|
// Cannot use for await without a variable. But the variable is never used. So eslint complains ¯\_(ツ)_/¯
|
|
for await (const _ of on(this._emitter, 'release')) { // eslint-disable-line
|
|
if (!this._locked) {
|
|
this._locked = true
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Releases the lock.
|
|
*/
|
|
release () {
|
|
this._locked = false
|
|
setImmediate(() => this._emitter.emit('release'))
|
|
}
|
|
}
|
|
|
|
module.exports = Lock
|