From bccc83329942fa83e4ae0c0485014ae7bce72be5 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 19 Feb 2016 08:35:46 -0800 Subject: [PATCH] play around with _lock method. --- lib/bcoin/chain.js | 199 ++++++++++++++++++--------------------------- 1 file changed, 81 insertions(+), 118 deletions(-) diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index daf1db78..4ca3f75e 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -39,10 +39,9 @@ function Chain(options) { this.loading = false; this.mempool = options.mempool; this.blockdb = options.blockdb; - this.locked = false; + // this.locked = false; this.handling = false; this.busy = false; - this.jobQueue = []; this.pending = []; this.pendingBlocks = {}; this.pendingSize = 0; @@ -712,6 +711,51 @@ Chain.prototype.resetHeight = function resetHeight(height) { this.orphan.size = 0; }; +Chain.prototype._lock = function _lock(func, args) { + var self = this; + var block; + + if (this.busy) { + if (func === Chain.add) { + block = args[0]; + this.pendingBlocks[block.hash('hex')] = true; + assert(typeof block._size === 'number'); + this.pendingSize += block._size; + if (this.pendingSize > this.pendingLimit) { + utils.debug('Warning: %dmb of pending blocks.', + utils.mb(this.pendingSize)); + } + } + this.pending.push([func, args]); + return; + } + + this.busy = true; + + return function unlock() { + var item, block; + + if (func === Chain.add) { + block = args[0]; + delete self.pendingBlocks[block.hash('hex')]; + assert(typeof block._size === 'number'); + self.pendingSize -= block._size; + } + + self.busy = false; + + if (func === Chain.add && self.pendingSize === 0) + self.emit('flush'); + + if (self.pending.length === 0) { + return; + } + + item = self.pending.shift(); + item[0].apply(self, item[1]); + }; +}; + Chain.prototype.resetHeightAsync = function resetHeightAsync(height, callback) { var self = this; var lock = this.lock; @@ -912,96 +956,12 @@ Chain.prototype._onFlush = function _onFlush(callback) { this.once('flush', callback); }; -Chain.prototype._onUnlock = function _onUnlock(callback) { - if (!this.handling) - return callback(); - - this.once('unlock', callback); -}; - -// REALLY? Did it have to be this fucking complicated? -Chain.prototype._onReady = function _onReady(internal, callback) { - var self = this; - - if (typeof internal === 'function') { - callback = internal; - internal = false; - } - - if (internal) - return callback(function() {}); - - if (this.busy) { - this.jobQueue.push(callback); - return; - } - - self.busy = true; - - this._onUnlock(function() { - assert(!self.locked); - assert(!self.handling); - assert(self.busy); - - self.locked = true; - - callback(function unlock() { - var item; - - assert(self.locked); - assert(!self.handling); - assert(self.busy); - - self.busy = false; - self.locked = false; - - if (self.jobQueue.length > 0) { - item = self.jobQueue.shift(); - self._onReady(false, item); - return; - } - - if (self.pending.length === 0) - return; - - item = self.pending.shift(); - delete self.pendingBlocks[item[0].hash('hex')]; - self.pendingSize -= item[0].getSize(); - - self.add(item[0], item[1], item[2]); - }); - }); -}; - -function wrap(method) { - return function wrapper() { - var self = this; - var args = Array.prototype.slice.call(arguments); - var callback, internal; - - if (typeof args[args.length - 1] === 'boolean') - internal = args.pop(); - - if (typeof args[args.length - 1] === 'function') - callback = args.pop(); - - this._onReady(internal, function(unlock) { - args.push(function() { - unlock(); - - if (!callback) - return; - - return callback.apply(null, arguments); - }); - - method.apply(self, args); - - if (!callback) - unlock(); - }); - }; -} +// Chain.prototype._onUnlock = function _onUnlock(callback) { +// if (!this.handling) +// return callback(); +// +// this.once('unlock', callback); +// }; Chain.prototype.add = function add(initial, peer, callback) { var self = this; @@ -1010,16 +970,20 @@ Chain.prototype.add = function add(initial, peer, callback) { assert(!this.loading); - if (this.locked) { - this.pending.push([initial, peer, callback]); - this.pendingBlocks[initial.hash('hex')] = true; - this.pendingSize += initial.getSize(); - if (this.pendingSize > this.pendingLimit) { - utils.debug('Warning: %dmb of pending blocks.', - utils.mb(this.pendingSize)); - } + var unlock = this._lock(add, [initial, peer, callback]); + if (!unlock) return; - } + + // if (this.locked) { + // this.pending.push([initial, peer, callback]); + // this.pendingBlocks[initial.hash('hex')] = true; + // this.pendingSize += initial.getSize(); + // if (this.pendingSize > this.pendingLimit) { + // utils.debug('Warning: %dmb of pending blocks.', + // utils.mb(this.pendingSize)); + // } + // return; + // } assert(!this.handling); @@ -1334,26 +1298,25 @@ Chain.prototype.add = function add(initial, peer, callback) { callback(null, total); self.total += total; - self.locked = false; + // self.locked = false; self.handling = false; - self.emit('unlock'); + unlock(); - if (self.locked) - return; - - // Start resolving the queue - // (I love asynchronous IO). - if (self.pending.length === 0) { - self.emit('flush'); - return; - } - - item = self.pending.shift(); - delete self.pendingBlocks[item[0].hash('hex')]; - self.pendingSize -= item[0].getSize(); - - self.add(item[0], item[1], item[2]); + // self.emit('unlock'); + // + // // Start resolving the queue + // // (I love asynchronous IO). + // if (self.pending.length === 0) { + // self.emit('flush'); + // return; + // } + // + // item = self.pending.shift(); + // delete self.pendingBlocks[item[0].hash('hex')]; + // self.pendingSize -= item[0].getSize(); + // + // self.add(item[0], item[1], item[2]); }); } };