diff options
Diffstat (limited to 'node_modules/when/guard.js')
-rw-r--r-- | node_modules/when/guard.js | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/node_modules/when/guard.js b/node_modules/when/guard.js new file mode 100644 index 000000000..38924cae0 --- /dev/null +++ b/node_modules/when/guard.js @@ -0,0 +1,72 @@ +/** @license MIT License (c) copyright 2011-2013 original author or authors */ + +/** + * Generalized promise concurrency guard + * Adapted from original concept by Sakari Jokinen (Rocket Pack, Ltd.) + * + * @author Brian Cavalier + * @author John Hann + * @contributor Sakari Jokinen + */ +(function(define) { +define(function(require) { + + var when = require('./when'); + var slice = Array.prototype.slice; + + guard.n = n; + + return guard; + + /** + * Creates a guarded version of f that can only be entered when the supplied + * condition allows. + * @param {function} condition represents a critical section that may only + * be entered when allowed by the condition + * @param {function} f function to guard + * @returns {function} guarded version of f + */ + function guard(condition, f) { + return function() { + var args = slice.call(arguments); + + return when(condition()).withThis(this).then(function(exit) { + return when(f.apply(this, args))['finally'](exit); + }); + }; + } + + /** + * Creates a condition that allows only n simultaneous executions + * of a guarded function + * @param {number} allowed number of allowed simultaneous executions + * @returns {function} condition function which returns a promise that + * fulfills when the critical section may be entered. The fulfillment + * value is a function ("notifyExit") that must be called when the critical + * section has been exited. + */ + function n(allowed) { + var count = 0; + var waiting = []; + + return function enter() { + return when.promise(function(resolve) { + if(count < allowed) { + resolve(exit); + } else { + waiting.push(resolve); + } + count += 1; + }); + }; + + function exit() { + count = Math.max(count - 1, 0); + if(waiting.length > 0) { + waiting.shift()(exit); + } + } + } + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); })); |