Files
jsrt/lib/stdlib/loop.js
T
2026-10-08 08:53:11 +00:00

44 lines
1.4 KiB
JavaScript

// The event loop's JS side. The host owns the loop (see lib/rt/jsrt.h). A
// macrotask is an IO op or a timer, which the host runs: it calls
// `__complete(h)` when op `h` is done. A microtask is a promise job, in
// `__microtasks`. After the program's top level, end.js runs all microtasks,
// and after each macrotask, `__complete` does
// What to do when IO op `h` completes: `__pending[h]`, a fn that gets `h`.
// Handles are small ints, and a handle is used again after its op completes
const __pending = [];
// Promise jobs, in order. `head` is the next one, so that taking a job does
// not move the others. A job is a closure, which keeps its own data: the
// handler and the value that it is called with. So each handler gets only the
// values of its own promise (see `docs/model.md`, section 3.3)
const __microtasks = { jobs: [], head: 0 };
function __queue_job(job) {
__microtasks.jobs.push(job);
}
function __drain_microtasks() {
const q = __microtasks;
while (q.head < q.jobs.length) {
const job = q.jobs[q.head];
q.jobs[q.head] = undefined;
q.head++;
job();
}
q.jobs.length = 0;
q.head = 0;
}
// What the host calls when op `h` is done: its callback, then the microtasks
function __complete(h) {
const done = __pending[h];
__pending[h] = undefined;
if (done !== undefined) done(h);
__drain_microtasks();
}
__link_host_complete(__complete);