utils: start using bmutex.
This commit is contained in:
parent
a79c2b0b1a
commit
4535cd1827
@ -9,20 +9,20 @@
|
||||
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const Logger = require('blgr');
|
||||
const {Lock} = require('bmutex');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
const AsyncEmitter = require('../utils/asyncemitter');
|
||||
const Network = require('../protocol/network');
|
||||
const Logger = require('blgr');
|
||||
const ChainDB = require('./chaindb');
|
||||
const common = require('./common');
|
||||
const consensus = require('../protocol/consensus');
|
||||
const util = require('../utils/util');
|
||||
const Lock = require('../utils/lock');
|
||||
const LRU = require('../utils/lru');
|
||||
const ChainEntry = require('./chainentry');
|
||||
const CoinView = require('../coins/coinview');
|
||||
const Script = require('../script/script');
|
||||
const {VerifyError} = require('../protocol/errors');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
const thresholdStates = common.thresholdStates;
|
||||
|
||||
/**
|
||||
|
||||
@ -9,10 +9,10 @@
|
||||
|
||||
const assert = require('assert');
|
||||
const EventEmitter = require('events');
|
||||
const {Lock} = require('bmutex');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
const util = require('../utils/util');
|
||||
const mine = require('./mine');
|
||||
const Lock = require('../utils/lock');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
|
||||
/**
|
||||
* CPU miner.
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
const assert = require('assert');
|
||||
const EventEmitter = require('events');
|
||||
const {Lock} = require('bmutex');
|
||||
const {format} = require('util');
|
||||
const tcp = require('btcp');
|
||||
const Logger = require('blgr');
|
||||
@ -20,7 +21,6 @@ const packets = require('./packets');
|
||||
const consensus = require('../protocol/consensus');
|
||||
const common = require('./common');
|
||||
const InvItem = require('../primitives/invitem');
|
||||
const Lock = require('../utils/lock');
|
||||
const BIP151 = require('./bip151');
|
||||
const BIP150 = require('./bip150');
|
||||
const BIP152 = require('./bip152');
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
const assert = require('assert');
|
||||
const EventEmitter = require('events');
|
||||
const {Lock} = require('bmutex');
|
||||
const IP = require('binet');
|
||||
const dns = require('bdns');
|
||||
const tcp = require('btcp');
|
||||
@ -25,7 +26,6 @@ const Address = require('../primitives/address');
|
||||
const BIP150 = require('./bip150');
|
||||
const BIP151 = require('./bip151');
|
||||
const BIP152 = require('./bip152');
|
||||
const Lock = require('../utils/lock');
|
||||
const Network = require('../protocol/network');
|
||||
const Peer = require('./peer');
|
||||
const external = require('./external');
|
||||
|
||||
@ -8,12 +8,16 @@
|
||||
|
||||
const assert = require('assert');
|
||||
const bweb = require('bweb');
|
||||
const util = require('../utils/util');
|
||||
const {Lock} = require('bmutex');
|
||||
const IP = require('binet');
|
||||
const hash160 = require('bcrypto/lib/hash160');
|
||||
const hash256 = require('bcrypto/lib/hash256');
|
||||
const ccmp = require('bcrypto/lib/ccmp');
|
||||
const common = require('../blockchain/common');
|
||||
const secp256k1 = require('bcrypto/lib/secp256k1');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
const Validator = require('bval/lib/validator');
|
||||
const util = require('../utils/util');
|
||||
const common = require('../blockchain/common');
|
||||
const Amount = require('../btc/amount');
|
||||
const NetAddress = require('../primitives/netaddress');
|
||||
const Script = require('../script/script');
|
||||
@ -28,12 +32,8 @@ const Network = require('../protocol/network');
|
||||
const Outpoint = require('../primitives/outpoint');
|
||||
const Output = require('../primitives/output');
|
||||
const TX = require('../primitives/tx');
|
||||
const IP = require('binet');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
const consensus = require('../protocol/consensus');
|
||||
const Validator = require('bval/lib/validator');
|
||||
const pkg = require('../pkg');
|
||||
const Lock = require('../utils/lock');
|
||||
const RPCBase = bweb.RPC;
|
||||
const RPCError = bweb.RPCError;
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const Lock = require('../utils/lock');
|
||||
const {Lock} = require('bmutex');
|
||||
const Chain = require('../blockchain/chain');
|
||||
const Pool = require('../net/pool');
|
||||
const Node = require('./node');
|
||||
|
||||
@ -15,7 +15,5 @@ exports.binary = require('./binary');
|
||||
exports.fixed = require('./fixed');
|
||||
exports.Heap = require('./heap');
|
||||
exports.List = require('./list');
|
||||
exports.Lock = require('./lock');
|
||||
exports.LRU = require('./lru');
|
||||
exports.MappedLock = require('./mappedlock');
|
||||
exports.util = require('./util');
|
||||
|
||||
@ -1,215 +0,0 @@
|
||||
/*!
|
||||
* lock.js - lock and queue for bcoin
|
||||
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
/**
|
||||
* Mutex Lock
|
||||
* @alias module:utils.Lock
|
||||
*/
|
||||
|
||||
class Lock {
|
||||
/**
|
||||
* Create a lock.
|
||||
* @constructor
|
||||
* @param {Boolean?} named - Whether to
|
||||
* maintain a map of queued jobs by job name.
|
||||
*/
|
||||
|
||||
constructor(named = false) {
|
||||
this.named = named === true;
|
||||
|
||||
this.jobs = [];
|
||||
this.busy = false;
|
||||
this.destroyed = false;
|
||||
|
||||
this.map = new Map();
|
||||
this.current = null;
|
||||
|
||||
this.unlocker = this.unlock.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a closure scoped lock.
|
||||
* @param {Boolean?} named
|
||||
* @returns {Function} Lock method.
|
||||
*/
|
||||
|
||||
static create(named) {
|
||||
const lock = new Lock(named);
|
||||
return function _lock(arg1, arg2) {
|
||||
return lock.lock(arg1, arg2);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the lock has a pending
|
||||
* job or a job in progress (by name).
|
||||
* @param {String} name
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
has(name) {
|
||||
assert(this.named, 'Must use named jobs.');
|
||||
|
||||
if (this.current === name)
|
||||
return true;
|
||||
|
||||
return this.pending(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the lock has
|
||||
* a pending job by name.
|
||||
* @param {String} name
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
pending(name) {
|
||||
assert(this.named, 'Must use named jobs.');
|
||||
|
||||
const count = this.map.get(name);
|
||||
|
||||
if (count == null)
|
||||
return false;
|
||||
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock the parent object and all its methods
|
||||
* which use the lock. Begin to queue calls.
|
||||
* @param {String?} name - Job name.
|
||||
* @param {Boolean?} force - Bypass the lock.
|
||||
* @returns {Promise} - Returns {Function}, must be
|
||||
* called once the method finishes executing in order
|
||||
* to resolve the queue.
|
||||
*/
|
||||
|
||||
lock(arg1, arg2) {
|
||||
let name, force;
|
||||
|
||||
if (this.named) {
|
||||
name = arg1 || null;
|
||||
force = arg2 || false;
|
||||
} else {
|
||||
name = null;
|
||||
force = arg1 || false;
|
||||
}
|
||||
|
||||
if (this.destroyed)
|
||||
return Promise.reject(new Error('Lock is destroyed.'));
|
||||
|
||||
if (force) {
|
||||
assert(this.busy);
|
||||
return Promise.resolve(nop);
|
||||
}
|
||||
|
||||
if (this.busy) {
|
||||
if (name) {
|
||||
const count = this.map.get(name) || 0;
|
||||
this.map.set(name, count + 1);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this.jobs.push(new Job(resolve, reject, name));
|
||||
});
|
||||
}
|
||||
|
||||
this.busy = true;
|
||||
this.current = name;
|
||||
|
||||
return Promise.resolve(this.unlocker);
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual unlock callback.
|
||||
* @private
|
||||
*/
|
||||
|
||||
unlock() {
|
||||
assert(this.destroyed || this.busy);
|
||||
|
||||
this.busy = false;
|
||||
this.current = null;
|
||||
|
||||
if (this.jobs.length === 0)
|
||||
return;
|
||||
|
||||
assert(!this.destroyed);
|
||||
|
||||
const job = this.jobs.shift();
|
||||
|
||||
if (job.name) {
|
||||
let count = this.map.get(job.name);
|
||||
assert(count > 0);
|
||||
if (--count === 0)
|
||||
this.map.delete(job.name);
|
||||
else
|
||||
this.map.set(job.name, count);
|
||||
}
|
||||
|
||||
this.busy = true;
|
||||
this.current = job.name;
|
||||
|
||||
job.resolve(this.unlocker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the lock. Purge all pending calls.
|
||||
*/
|
||||
|
||||
destroy() {
|
||||
assert(!this.destroyed, 'Lock is already destroyed.');
|
||||
|
||||
this.destroyed = true;
|
||||
|
||||
const jobs = this.jobs;
|
||||
|
||||
this.busy = false;
|
||||
this.jobs = [];
|
||||
this.map.clear();
|
||||
this.current = null;
|
||||
|
||||
for (const job of jobs)
|
||||
job.reject(new Error('Lock was destroyed.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock Job
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
class Job {
|
||||
/**
|
||||
* Create a lock job.
|
||||
* @constructor
|
||||
* @param {Function} resolve
|
||||
* @param {Function} reject
|
||||
* @param {String?} name
|
||||
*/
|
||||
|
||||
constructor(resolve, reject, name) {
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
this.name = name || null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function nop() {}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = Lock;
|
||||
@ -1,181 +0,0 @@
|
||||
/*!
|
||||
* mappedlock.js - lock and queue for bcoin
|
||||
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
/**
|
||||
* Mapped Lock
|
||||
* @alias module:utils.MappedLock
|
||||
*/
|
||||
|
||||
class MappedLock {
|
||||
/**
|
||||
* Create a mapped lock.
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
constructor() {
|
||||
this.jobs = new Map();
|
||||
this.busy = new Set();
|
||||
this.destroyed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a closure scoped lock.
|
||||
* @returns {Function} Lock method.
|
||||
*/
|
||||
|
||||
static create() {
|
||||
const lock = new MappedLock();
|
||||
return function _lock(key, force) {
|
||||
return lock.lock(key, force);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the lock has a pending
|
||||
* job or a job in progress (by name).
|
||||
* @param {String} name
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
has(name) {
|
||||
return this.busy.has(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the lock has
|
||||
* a pending job by name.
|
||||
* @param {String} name
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
pending(name) {
|
||||
return this.jobs.has(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock the parent object and all its methods
|
||||
* which use the lock with a specified key.
|
||||
* Begin to queue calls.
|
||||
* @param {String|Number} key
|
||||
* @param {Boolean} [force=false] - Force a call.
|
||||
* @returns {Promise} - Returns {Function}, must be
|
||||
* called once the method finishes executing in order
|
||||
* to resolve the queue.
|
||||
*/
|
||||
|
||||
lock(key, force = false) {
|
||||
if (this.destroyed)
|
||||
return Promise.reject(new Error('Lock is destroyed.'));
|
||||
|
||||
if (key == null)
|
||||
return Promise.resolve(nop);
|
||||
|
||||
if (force) {
|
||||
assert(this.busy.has(key));
|
||||
return Promise.resolve(nop);
|
||||
}
|
||||
|
||||
if (this.busy.has(key)) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.jobs.has(key))
|
||||
this.jobs.set(key, []);
|
||||
this.jobs.get(key).push(new Job(resolve, reject));
|
||||
});
|
||||
}
|
||||
|
||||
this.busy.add(key);
|
||||
|
||||
return Promise.resolve(this.unlock(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an unlock callback.
|
||||
* @private
|
||||
* @param {String} key
|
||||
* @returns {Function} Unlocker.
|
||||
*/
|
||||
|
||||
unlock(key) {
|
||||
const self = this;
|
||||
return function unlocker() {
|
||||
const jobs = self.jobs.get(key);
|
||||
|
||||
assert(self.destroyed || self.busy.has(key));
|
||||
self.busy.delete(key);
|
||||
|
||||
if (!jobs)
|
||||
return;
|
||||
|
||||
assert(!self.destroyed);
|
||||
|
||||
const job = jobs.shift();
|
||||
assert(job);
|
||||
|
||||
if (jobs.length === 0)
|
||||
self.jobs.delete(key);
|
||||
|
||||
self.busy.add(key);
|
||||
|
||||
job.resolve(unlocker);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the lock. Purge all pending calls.
|
||||
*/
|
||||
|
||||
destroy() {
|
||||
assert(!this.destroyed, 'Lock is already destroyed.');
|
||||
|
||||
const map = this.jobs;
|
||||
|
||||
this.destroyed = true;
|
||||
|
||||
this.jobs = new Map();
|
||||
this.busy = new Map();
|
||||
|
||||
for (const jobs of map.values()) {
|
||||
for (const job of jobs)
|
||||
job.reject(new Error('Lock was destroyed.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock Job
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
class Job {
|
||||
/**
|
||||
* Create a lock job.
|
||||
* @constructor
|
||||
* @param {Function} resolve
|
||||
* @param {Function} reject
|
||||
*/
|
||||
|
||||
constructor(resolve, reject) {
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function nop() {}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = MappedLock;
|
||||
@ -7,9 +7,7 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const Network = require('../protocol/network');
|
||||
const util = require('../utils/util');
|
||||
const Lock = require('../utils/lock');
|
||||
const {Lock} = require('bmutex');
|
||||
const random = require('bcrypto/lib/random');
|
||||
const cleanse = require('bcrypto/lib/cleanse');
|
||||
const aes = require('bcrypto/lib/aes');
|
||||
@ -19,6 +17,8 @@ const scrypt = require('bcrypto/lib/scrypt');
|
||||
const BufferReader = require('bbuf/lib/reader');
|
||||
const StaticWriter = require('bbuf/lib/staticwriter');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
const Network = require('../protocol/network');
|
||||
const util = require('../utils/util');
|
||||
const HD = require('../hd/hd');
|
||||
const Mnemonic = HD.Mnemonic;
|
||||
|
||||
|
||||
@ -7,11 +7,14 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const bweb = require('bweb');
|
||||
const fs = require('bfile');
|
||||
const {format} = require('util');
|
||||
const util = require('../utils/util');
|
||||
const bweb = require('bweb');
|
||||
const {Lock} = require('bmutex');
|
||||
const fs = require('bfile');
|
||||
const hash256 = require('bcrypto/lib/hash256');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
const Validator = require('bval/lib/validator');
|
||||
const util = require('../utils/util');
|
||||
const Amount = require('../btc/amount');
|
||||
const Script = require('../script/script');
|
||||
const Address = require('../primitives/address');
|
||||
@ -21,10 +24,7 @@ const MTX = require('../primitives/mtx');
|
||||
const Outpoint = require('../primitives/outpoint');
|
||||
const Output = require('../primitives/output');
|
||||
const TX = require('../primitives/tx');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
const pkg = require('../pkg');
|
||||
const Validator = require('bval/lib/validator');
|
||||
const Lock = require('../utils/lock');
|
||||
const common = require('./common');
|
||||
const RPCBase = bweb.RPC;
|
||||
const RPCError = bweb.RPCError;
|
||||
|
||||
@ -9,15 +9,15 @@
|
||||
|
||||
const assert = require('assert');
|
||||
const EventEmitter = require('events');
|
||||
const Network = require('../protocol/network');
|
||||
const {Lock} = require('bmutex');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
const Lock = require('../utils/lock');
|
||||
const hash160 = require('bcrypto/lib/hash160');
|
||||
const hash256 = require('bcrypto/lib/hash256');
|
||||
const cleanse = require('bcrypto/lib/cleanse');
|
||||
const BufferReader = require('bbuf/lib/reader');
|
||||
const StaticWriter = require('bbuf/lib/staticwriter');
|
||||
const base58 = require('bstr/lib/base58');
|
||||
const Network = require('../protocol/network');
|
||||
const TXDB = require('./txdb');
|
||||
const Path = require('./path');
|
||||
const common = require('./common');
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const EventEmitter = require('events');
|
||||
const Lock = require('bmutex/lib/lock');
|
||||
const MapLock = require('bmutex/lib/maplock');
|
||||
const BDB = require('bdb');
|
||||
const Logger = require('blgr');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
@ -17,8 +19,6 @@ const ccmp = require('bcrypto/lib/ccmp');
|
||||
const aes = require('bcrypto/lib/aes');
|
||||
const BloomFilter = require('bfilter/lib/bloom');
|
||||
const StaticWriter = require('bbuf/lib/staticwriter');
|
||||
const Lock = require('../utils/lock');
|
||||
const MappedLock = require('../utils/mappedlock');
|
||||
const Network = require('../protocol/network');
|
||||
const Path = require('./path');
|
||||
const common = require('./common');
|
||||
@ -65,7 +65,7 @@ function WalletDB(options) {
|
||||
this.rescanning = false;
|
||||
|
||||
// Wallet read lock.
|
||||
this.readLock = new MappedLock();
|
||||
this.readLock = new MapLock();
|
||||
|
||||
// Wallet write lock (creation and rename).
|
||||
this.writeLock = new Lock();
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
"bfile": "^0.0.1",
|
||||
"bfilter": "^0.0.1",
|
||||
"binet": "^0.0.1",
|
||||
"bmutex": "^0.0.1",
|
||||
"breq": "^0.0.1",
|
||||
"bsock": "^0.0.1",
|
||||
"bstr": "^0.0.1",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user