@ralphwetzel/node-red-mcu-plugin
Version:
Plugin to integrate Node-RED MCU Edition into the Node-RED Editor
103 lines (80 loc) • 2.72 kB
JavaScript
/*
This module is based on semaphore.js:
*
* @github https://github.com/abrkn/semaphore.js
* @author @abrkn
* @license MIT
* @version 67e14f8 on 20 May 2020
*
Adaptations to node-red-mcu by @ralphwetzel
https://github.com/ralphwetzel/node-red-ds2482-mcu
License: MIT
*/
;
var nextTick = function (fn) { setTimeout(fn, 0); }
if (typeof process != 'undefined' && process && typeof process.nextTick == 'function') {
// node.js and the like
nextTick = process.nextTick;
}
function semaphore(capacity) {
var semaphore = {
capacity: capacity || 1,
current: 0,
queue: [],
firstHere: false,
take: function() {
if (semaphore.firstHere === false) {
semaphore.current++;
semaphore.firstHere = true;
var isFirst = 1;
} else {
var isFirst = 0;
}
var item = { n: 1 };
if (typeof arguments[0] == 'function') {
item.task = arguments[0];
} else {
item.n = arguments[0];
}
if (arguments.length >= 2) {
if (typeof arguments[1] == 'function') item.task = arguments[1];
else item.n = arguments[1];
}
var task = item.task;
item.task = function() { task(semaphore.leave); };
if (semaphore.current + item.n - isFirst > semaphore.capacity) {
if (isFirst === 1) {
semaphore.current--;
semaphore.firstHere = false;
}
return semaphore.queue.push(item);
}
semaphore.current += item.n - isFirst;
item.task(semaphore.leave);
if (isFirst === 1) semaphore.firstHere = false;
},
leave: function(n) {
n = n || 1;
semaphore.current -= n;
if (!semaphore.queue.length) {
if (semaphore.current < 0) {
throw new Error('leave called too many times.');
}
return;
}
var item = semaphore.queue[0];
if (item.n + semaphore.current > semaphore.capacity) {
return;
}
semaphore.queue.shift();
semaphore.current += item.n;
nextTick(item.task);
},
available: function(n) {
n = n || 1;
return(semaphore.current + n <= semaphore.capacity);
}
};
return semaphore;
};
export { semaphore as default }