locker: fix destroy method.

This commit is contained in:
Christopher Jeffrey 2016-10-09 23:50:44 -07:00
parent 24cf42e6bf
commit 0802dbbb0f
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 59 additions and 25 deletions

View File

@ -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
*/

View File

@ -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();