From 3a1a1cc030fb7fc90d51ee27162466d6ac924926 Mon Sep 17 00:00:00 2001 From: snek Date: Fri, 2 Aug 2024 08:14:35 -0700 Subject: feat: async context (#24402) We are switching to ContinuationPreservedEmbedderData. This allows adding async context tracking to the various async operations that deno provides. Fixes: https://github.com/denoland/deno/issues/7010 Fixes: https://github.com/denoland/deno/issues/22886 Fixes: https://github.com/denoland/deno/issues/24368 --- ext/web/02_timers.js | 52 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 16 deletions(-) (limited to 'ext/web') diff --git a/ext/web/02_timers.js b/ext/web/02_timers.js index 559147861..a651df5a5 100644 --- a/ext/web/02_timers.js +++ b/ext/web/02_timers.js @@ -2,6 +2,10 @@ import { core, primordials } from "ext:core/mod.js"; import { op_defer, op_now } from "ext:core/ops"; +import { + getAsyncContext, + setAsyncContext, +} from "ext:runtime/01_async_context.js"; const { Uint8Array, Uint32Array, @@ -33,14 +37,16 @@ function checkThis(thisArg) { * Call a callback function immediately. */ function setImmediate(callback, ...args) { - if (args.length > 0) { - const unboundCallback = callback; - callback = () => ReflectApply(unboundCallback, globalThis, args); - } - - return core.queueImmediate( - callback, - ); + const asyncContext = getAsyncContext(); + return core.queueImmediate(() => { + const oldContext = getAsyncContext(); + try { + setAsyncContext(asyncContext); + return ReflectApply(callback, globalThis, args); + } finally { + setAsyncContext(oldContext); + } + }); } /** @@ -53,10 +59,17 @@ function setTimeout(callback, timeout = 0, ...args) { const unboundCallback = webidl.converters.DOMString(callback); callback = () => indirectEval(unboundCallback); } - if (args.length > 0) { - const unboundCallback = callback; - callback = () => ReflectApply(unboundCallback, globalThis, args); - } + const unboundCallback = callback; + const asyncContext = getAsyncContext(); + callback = () => { + const oldContext = getAsyncContext(); + try { + setAsyncContext(asyncContext); + ReflectApply(unboundCallback, globalThis, args); + } finally { + setAsyncContext(oldContext); + } + }; timeout = webidl.converters.long(timeout); return core.queueUserTimer( core.getTimerDepth() + 1, @@ -75,10 +88,17 @@ function setInterval(callback, timeout = 0, ...args) { const unboundCallback = webidl.converters.DOMString(callback); callback = () => indirectEval(unboundCallback); } - if (args.length > 0) { - const unboundCallback = callback; - callback = () => ReflectApply(unboundCallback, globalThis, args); - } + const unboundCallback = callback; + const asyncContext = getAsyncContext(); + callback = () => { + const oldContext = getAsyncContext(asyncContext); + try { + setAsyncContext(asyncContext); + ReflectApply(unboundCallback, globalThis, args); + } finally { + setAsyncContext(oldContext); + } + }; timeout = webidl.converters.long(timeout); return core.queueUserTimer( core.getTimerDepth() + 1, -- cgit v1.2.3