aboutsummaryrefslogtreecommitdiff
path: root/node_modules/when/guard.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/when/guard.js')
-rw-r--r--node_modules/when/guard.js72
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); }));