diff options
Diffstat (limited to 'src/bun.js')
-rw-r--r-- | src/bun.js/bindings/ScriptExecutionContext.h | 9 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 6 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.h | 1 | ||||
-rw-r--r-- | src/bun.js/bindings/webcore/AbortSignal.cpp | 26 | ||||
-rw-r--r-- | src/bun.js/event_loop.zig | 14 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 5 |
6 files changed, 48 insertions, 13 deletions
diff --git a/src/bun.js/bindings/ScriptExecutionContext.h b/src/bun.js/bindings/ScriptExecutionContext.h index 1643820dd..5f6c56a90 100644 --- a/src/bun.js/bindings/ScriptExecutionContext.h +++ b/src/bun.js/bindings/ScriptExecutionContext.h @@ -132,6 +132,15 @@ public: reinterpret_cast<Zig::GlobalObject*>(m_globalObject)->queueTask(task); } // Executes the task on context's thread asynchronously. + void postTaskOnTimeout(EventLoopTask* task, Seconds timeout) + { + reinterpret_cast<Zig::GlobalObject*>(m_globalObject)->queueTaskOnTimeout(task, static_cast<int>(timeout.milliseconds())); + } // Executes the task on context's thread asynchronously. + void postTaskOnTimeout(Function<void(ScriptExecutionContext&)>&& lambda, Seconds timeout) + { + auto* task = new EventLoopTask(WTFMove(lambda)); + postTaskOnTimeout(task, timeout); + } template<typename... Arguments> void postCrossThreadTask(Arguments&&... arguments) { diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 50a07f06e..775382d82 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -3368,6 +3368,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor) } extern "C" void Bun__queueTask(JSC__JSGlobalObject*, WebCore::EventLoopTask* task); +extern "C" void Bun__queueTaskWithTimeout(JSC__JSGlobalObject*, WebCore::EventLoopTask* task, int timeout); extern "C" void Bun__queueTaskConcurrently(JSC__JSGlobalObject*, WebCore::EventLoopTask* task); extern "C" void Bun__performTask(Zig::GlobalObject* globalObject, WebCore::EventLoopTask* task) { @@ -3379,6 +3380,11 @@ void GlobalObject::queueTask(WebCore::EventLoopTask* task) Bun__queueTask(this, task); } +void GlobalObject::queueTaskOnTimeout(WebCore::EventLoopTask* task, int timeout) +{ + Bun__queueTaskWithTimeout(this, task, timeout); +} + void GlobalObject::queueTaskConcurrently(WebCore::EventLoopTask* task) { Bun__queueTaskConcurrently(this, task); diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index bcc6cb804..90d67d34f 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -149,6 +149,7 @@ public: WebCore::ScriptExecutionContext* scriptExecutionContext() const; void queueTask(WebCore::EventLoopTask* task); + void queueTaskOnTimeout(WebCore::EventLoopTask* task, int timeout); void queueTaskConcurrently(WebCore::EventLoopTask* task); JSDOMStructureMap& structures() WTF_REQUIRES_LOCK(m_gcLock) { return m_structures; } diff --git a/src/bun.js/bindings/webcore/AbortSignal.cpp b/src/bun.js/bindings/webcore/AbortSignal.cpp index 822595064..aa4143ebd 100644 --- a/src/bun.js/bindings/webcore/AbortSignal.cpp +++ b/src/bun.js/bindings/webcore/AbortSignal.cpp @@ -59,19 +59,19 @@ Ref<AbortSignal> AbortSignal::abort(JSDOMGlobalObject& globalObject, ScriptExecu Ref<AbortSignal> AbortSignal::timeout(ScriptExecutionContext& context, uint64_t milliseconds) { auto signal = adoptRef(*new AbortSignal(&context)); - // signal->setHasActiveTimeoutTimer(true); - // auto action = [signal](ScriptExecutionContext& context) mutable { - // signal->setHasActiveTimeoutTimer(false); - - // auto* globalObject = JSC::jsCast<JSDOMGlobalObject*>(context.globalObject()); - // if (!globalObject) - // return; - - // auto& vm = globalObject->vm(); - // Locker locker { vm.apiLock() }; - // signal->signalAbort(toJS(globalObject, globalObject, DOMException::create(TimeoutError))); - // }; - // DOMTimer::install(context, WTFMove(action), Seconds::fromMilliseconds(milliseconds), true); + signal->setHasActiveTimeoutTimer(true); + auto action = [signal](ScriptExecutionContext& context) mutable { + signal->setHasActiveTimeoutTimer(false); + + auto* globalObject = JSC::jsCast<JSDOMGlobalObject*>(context.jsGlobalObject()); + if (!globalObject) + return; + + auto& vm = globalObject->vm(); + Locker locker { vm.apiLock() }; + signal->signalAbort(toJS(globalObject, globalObject, DOMException::create(TimeoutError))); + }; + context.postTaskOnTimeout(WTFMove(action), Seconds::fromMilliseconds(milliseconds)); return signal; } diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig index 0e2d16486..6f7f18f0a 100644 --- a/src/bun.js/event_loop.zig +++ b/src/bun.js/event_loop.zig @@ -566,6 +566,20 @@ pub const EventLoop = struct { this.tasks.writeItem(task) catch unreachable; } + pub fn enqueueTaskWithTimeout(this: *EventLoop, task: Task, timeout: i32) void { + // TODO: make this more efficient! + var loop = this.virtual_machine.uws_event_loop orelse @panic("EventLoop.enqueueTaskWithTimeout: uSockets event loop is not initialized"); + var timer = uws.Timer.createFallthrough(loop, task.ptr()); + timer.set(task.ptr(), callTask, timeout, 0); + } + + pub fn callTask(timer: *uws.Timer) callconv(.C) void { + var task = Task.from(timer.as(*anyopaque)); + timer.deinit(); + + JSC.VirtualMachine.vm.enqueueTask(task); + } + pub fn ensureWaker(this: *EventLoop) void { JSC.markBinding(@src()); if (this.virtual_machine.uws_event_loop == null) { diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index f1f77aeaa..c9b165def 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -280,6 +280,7 @@ comptime { _ = Bun__onDidAppendPlugin; _ = Bun__readOriginTimerStart; _ = Bun__reportUnhandledError; + _ = Bun__queueTaskWithTimeout; } } @@ -289,6 +290,10 @@ pub export fn Bun__queueTask(global: *JSGlobalObject, task: *JSC.CppTask) void { global.bunVM().eventLoop().enqueueTask(Task.init(task)); } +pub export fn Bun__queueTaskWithTimeout(global: *JSGlobalObject, task: *JSC.CppTask, milliseconds: i32) void { + global.bunVM().eventLoop().enqueueTaskWithTimeout(Task.init(task), milliseconds); +} + pub export fn Bun__reportUnhandledError(globalObject: *JSGlobalObject, value: JSValue) callconv(.C) JSValue { var jsc_vm = globalObject.bunVM(); jsc_vm.onUnhandledError(globalObject, value); |