UNPKG

state-trooper

Version:
83 lines (71 loc) • 1.88 kB
"use strict"; // TODO: Use process.nextTick if it's available since it's more // efficient // http://howtonode.org/understanding-process-next-tick // Maybe we don't even need to queue ourselves in that case? // XXX: But http://blog.nodejs.org/2013/03/11/node-v0-10-0-stable/ // Looks like it will blow up the stack (or is that just about // pre-empting IO (but that's already bad enough IMO)?) // Looks like // http://nodejs.org/api/process.html#process_process_nexttick_callback // is the equivalent of our TASK_BATCH_SIZE var buffers = require("./buffers"); var TASK_BATCH_SIZE = 1024; var tasks = buffers.ring(32); var running = false; var queued = false; var queue_dispatcher; function process_messages() { running = true; queued = false; var count = 0; while (true) { var task = tasks.pop(); if (task === buffers.EMPTY) { break; } // TODO: Don't we need a try/finally here? task(); if (count >= TASK_BATCH_SIZE) { break; } count ++; } running = false; if (tasks.length > 0) { queue_dispatcher(); } } if (typeof MessageChannel !== "undefined") { var message_channel = new MessageChannel(); message_channel.port1.onmessage = function(_) { process_messages(); }; queue_dispatcher = function() { if (!(queued && running)) { queued = true; message_channel.port2.postMessage(0); } }; } else if (typeof setImmediate !== "undefined") { queue_dispatcher = function() { if (!(queued && running)) { queued = true; setImmediate(process_messages); } }; } else { queue_dispatcher = function() { if (!(queued && running)) { queued = true; setTimeout(process_messages, 0); } }; } exports.run = function (f) { tasks.unbounded_unshift(f); queue_dispatcher(); }; exports.queue_delay = function(f, delay) { setTimeout(f, delay); };