diff options
Diffstat (limited to 'core/01_core.js')
-rw-r--r-- | core/01_core.js | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/core/01_core.js b/core/01_core.js index 4cefb52e9..6231c0766 100644 --- a/core/01_core.js +++ b/core/01_core.js @@ -133,13 +133,48 @@ return promiseRing[idx] != NO_PROMISE; } - function opresolve() { - for (let i = 0; i < arguments.length; i += 2) { + const macrotaskCallbacks = []; + const nextTickCallbacks = []; + + function setMacrotaskCallback(cb) { + ArrayPrototypePush(macrotaskCallbacks, cb); + } + + function setNextTickCallback(cb) { + ArrayPrototypePush(nextTickCallbacks, cb); + } + + // This function has variable number of arguments. The last argument describes + // if there's a "next tick" scheduled by the Node.js compat layer. Arguments + // before last are alternating integers and any values that describe the + // responses of async ops. + function eventLoopTick() { + // First respond to all pending ops. + for (let i = 0; i < arguments.length - 1; i += 2) { const promiseId = arguments[i]; const res = arguments[i + 1]; const promise = getPromise(promiseId); promise.resolve(res); } + // Drain nextTick queue if there's a tick scheduled. + if (arguments[arguments.length - 1]) { + for (let i = 0; i < nextTickCallbacks.length; i++) { + nextTickCallbacks[i](); + } + } else { + ops.op_run_microtasks(); + } + // Finally drain macrotask queue. + for (let i = 0; i < macrotaskCallbacks.length; i++) { + const cb = macrotaskCallbacks[i]; + while (true) { + const res = cb(); + ops.op_run_microtasks(); + if (res === true) { + break; + } + } + } } function registerErrorClass(className, errorClass) { @@ -406,7 +441,7 @@ registerErrorBuilder, registerErrorClass, buildCustomError, - opresolve, + eventLoopTick, BadResource, BadResourcePrototype, Interrupted, @@ -428,8 +463,8 @@ writeSync: (rid, buffer) => ops.op_write_sync(rid, buffer), shutdown: opAsync.bind(null, "op_shutdown"), print: (msg, isErr) => ops.op_print(msg, isErr), - setMacrotaskCallback: (fn) => ops.op_set_macrotask_callback(fn), - setNextTickCallback: (fn) => ops.op_set_next_tick_callback(fn), + setMacrotaskCallback, + setNextTickCallback, runMicrotasks: () => ops.op_run_microtasks(), hasTickScheduled: () => ops.op_has_tick_scheduled(), setHasTickScheduled: (bool) => ops.op_set_has_tick_scheduled(bool), |