From 0802dbbb0f627b1bf56a0d0d76151499ef33bcd0 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sun, 9 Oct 2016 23:50:44 -0700 Subject: [PATCH] locker: fix destroy method. --- lib/utils/locker.js | 81 ++++++++++++++++++++++++++++++-------------- lib/wallet/wallet.js | 3 ++ 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/lib/utils/locker.js b/lib/utils/locker.js index 76de8185..e70e0b13 100644 --- a/lib/utils/locker.js +++ b/lib/utils/locker.js @@ -28,6 +28,7 @@ function Locker(add) { this.jobs = []; this.busy = false; + this.destroyed = false; this.pending = []; this.pendingMap = {}; @@ -81,6 +82,9 @@ Locker.prototype.lock = function lock(arg1, arg2) { force = arg1; } + if (this.destroyed) + return Promise.reject(new Error('Locker is destroyed.')); + if (force) { assert(this.busy); return Promise.resolve(utils.nop); @@ -91,8 +95,9 @@ Locker.prototype.lock = function lock(arg1, arg2) { this.pending.push(object); this.pendingMap[object.hash('hex')] = true; } + return new Promise(function(resolve, reject) { - self.jobs.push([resolve, object]); + self.jobs.push(new Job(resolve, reject, object)); }); } @@ -107,7 +112,7 @@ Locker.prototype.lock = function lock(arg1, arg2) { */ Locker.prototype.unlock = function unlock() { - var item, resolve, object; + var job; this.busy = false; @@ -117,18 +122,21 @@ Locker.prototype.unlock = function unlock() { if (this.jobs.length === 0) return; - item = this.jobs.shift(); - resolve = item[0]; - object = item[1]; + job = this.jobs.shift(); - if (object) { - assert(object === this.pending.shift()); - delete this.pendingMap[object.hash('hex')]; + if (this.destroyed) { + job.reject(new Error('Locker is destroyed.')); + return; + } + + if (job.object) { + assert(job.object === this.pending.shift()); + delete this.pendingMap[job.object.hash('hex')]; } this.busy = true; - resolve(this.unlocker); + job.resolve(this.unlocker); }; /** @@ -136,10 +144,7 @@ Locker.prototype.unlock = function unlock() { */ Locker.prototype.destroy = function destroy() { - this.jobs.length = 0; - this.busy = false; - this.pending.length = 0; - this.pendingMap = {}; + this.destroyed = true; }; /** @@ -152,10 +157,10 @@ Locker.prototype.onDrain = function onDrain() { assert(this.add, 'Cannot wait for drain without add method.'); - return new Promise(function(resolve, reject) { - if (self.pending.length === 0) - return resolve(); + if (this.pending.length === 0) + return Promise.resolve(null); + return new Promise(function(resolve, reject) { self.once('drain', resolve); }); }; @@ -173,6 +178,7 @@ function MappedLock() { this.jobs = {}; this.busy = {}; + this.destroyed = false; } /** @@ -203,8 +209,14 @@ MappedLock.create = function create() { MappedLock.prototype.lock = function lock(key, force) { var self = this; - if (force || key == null) { - assert(key == null || this.busy[key]); + if (this.destroyed) + return Promise.reject(new Error('Locker is destroyed.')); + + if (key == null) + return Promise.resolve(utils.nop); + + if (force) { + assert(this.busy[key]); return Promise.resolve(utils.nop); } @@ -212,7 +224,7 @@ MappedLock.prototype.lock = function lock(key, force) { return new Promise(function(resolve, reject) { if (!self.jobs[key]) self.jobs[key] = []; - self.jobs[key].push(resolve); + self.jobs[key].push(new Job(resolve, reject)); }); } @@ -232,22 +244,27 @@ MappedLock.prototype.unlock = function unlock(key) { var self = this; return function unlocker() { var jobs = self.jobs[key]; - var resolve; + var job; delete self.busy[key]; if (!jobs) return; - resolve = jobs.shift(); - assert(resolve); + job = jobs.shift(); + assert(job); if (jobs.length === 0) delete self.jobs[key]; + if (self.destroyed) { + job.reject(new Error('Locker is destroyed.')); + return; + } + self.busy[key] = true; - resolve(unlocker); + job.resolve(unlocker); }; }; @@ -256,10 +273,24 @@ MappedLock.prototype.unlock = function unlock(key) { */ MappedLock.prototype.destroy = function destroy() { - this.jobs = {}; - this.busy = {}; + this.destroyed = true; }; +/** + * Locker Job + * @exports Job + * @constructor + * @param {Function} resolve + * @param {Function} reject + * @param {Object?} object + */ + +function Job(resolve, reject, object) { + this.resolve = resolve; + this.reject = reject; + this.object = object || null; +} + /* * Expose */ diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 54a1ef45..06414595 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -239,6 +239,9 @@ Wallet.prototype.destroy = co(function* destroy() { try { this.db.unregister(this); this.master.destroy(); + this.readLock.destroy(); + this.writeLock.destroy(); + this.fundLock.destroy(); } finally { unlock2(); unlock1();