diff options
-rw-r--r-- | src/deps/uws.zig | 24 | ||||
-rw-r--r-- | src/javascript/jsc/api/server.zig | 33 |
2 files changed, 34 insertions, 23 deletions
diff --git a/src/deps/uws.zig b/src/deps/uws.zig index 900cb4fae..6ec3e6855 100644 --- a/src/deps/uws.zig +++ b/src/deps/uws.zig @@ -27,6 +27,28 @@ pub const Loop = opaque { uws_loop_defer(this, user_data, Handler.callback); } + fn NewHandler(comptime UserType: type, comptime callback: fn (UserType) void) type { + return struct { + loop: *Loop, + pub fn remove(handler: @This()) void { + return uws_loop_removePostHandler(handler.loop, callback); + } + pub fn callback(data: *anyopaque, _: *Loop) callconv(.C) void { + const std = @import("std"); + callback(@ptrCast(UserType, @alignCast(@alignOf(std.meta.Child(UserType)), data))); + } + }; + } + + pub fn addPostHandler(this: *Loop, comptime UserType: type, ctx: UserType, comptime callback: fn (UserType) void) NewHandler(UserType, callback) { + const Handler = NewHandler(UserType, callback); + + uws_loop_addPostHandler(this, ctx, Handler.callback); + return Handler{ + .loop = this, + }; + } + extern fn uws_loop_defer(loop: *Loop, ctx: *anyopaque, cb: fn (ctx: *anyopaque) callconv(.C) void) void; extern fn uws_get_loop() ?*Loop; @@ -37,6 +59,8 @@ pub const Loop = opaque { extern fn us_wakeup_loop(loop: ?*Loop) void; extern fn us_loop_integrate(loop: ?*Loop) void; extern fn us_loop_iteration_number(loop: ?*Loop) c_longlong; + extern fn uws_loop_addPostHandler(loop: *Loop, ctx: *anyopaque, cb: (fn (ctx: *anyopaque, loop: *Loop) callconv(.C) void)) void; + extern fn uws_loop_removePostHandler(loop: *Loop, ctx: *anyopaque, cb: (fn (ctx: *anyopaque, loop: *Loop) callconv(.C) void)) void; }; const uintmax_t = c_ulong; diff --git a/src/javascript/jsc/api/server.zig b/src/javascript/jsc/api/server.zig index dc990b9eb..361be14f0 100644 --- a/src/javascript/jsc/api/server.zig +++ b/src/javascript/jsc/api/server.zig @@ -1185,7 +1185,6 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { base_url_string_for_joining: string = "", response_objects_pool: JSC.WebCore.Response.Pool = JSC.WebCore.Response.Pool{}, config: ServerConfig = ServerConfig{}, - next_tick_pending: bool = false, pending_requests: usize = 0, request_pool_allocator: std.mem.Allocator = undefined, has_js_deinited: bool = false, @@ -1279,24 +1278,15 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { } } + // if you run multiple servers simultaneously, this could break it + if (this.vm.uws_event_loop != null and uws.Loop.get().? == this.vm.uws_event_loop.?) { + this.vm.uws_event_loop = null; + } + this.app.destroy(); bun.default_allocator.destroy(this); } - pub fn nextTick(this: *ThisServer) void { - std.debug.assert(this.next_tick_pending); - - this.next_tick_pending = false; - this.vm.tick(); - } - - pub fn queueNextTick(this: *ThisServer) void { - std.debug.assert(!this.next_tick_pending); - - this.next_tick_pending = true; - uws.Loop.get().?.nextTick(*ThisServer, this, nextTick); - } - pub fn init(config: ServerConfig, globalThis: *JSGlobalObject) *ThisServer { var server = bun.default_allocator.create(ThisServer) catch @panic("Out of memory!"); server.* = .{ @@ -1376,13 +1366,18 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { } this.listener = socket; + const needs_post_handler = this.vm.uws_event_loop == null; this.vm.uws_event_loop = uws.Loop.get(); this.vm.response_objects_pool = &this.response_objects_pool; this.listen_callback = JSC.AnyTask.New(ThisServer, run).init(this); this.vm.eventLoop().enqueueTask(JSC.Task.init(&this.listen_callback)); + if (needs_post_handler) { + _ = this.vm.uws_event_loop.?.addPostHandler(*JSC.VirtualMachine.EventLoop, this.vm.eventLoop(), JSC.VirtualMachine.EventLoop.tick); + } } pub fn run(this: *ThisServer) void { + // this.app.addServerName(hostname_pattern: [*:0]const u8) this.app.run(); } @@ -1470,12 +1465,6 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { ctx.request_js_object = args[0]; JSC.C.JSValueProtect(this.globalThis.ref(), args[0]); ctx.response_jsvalue = JSC.C.JSObjectCallAsFunctionReturnValue(this.globalThis.ref(), this.config.onRequest.asObjectRef(), this.thisObject.asObjectRef(), 1, &args); - var needs_tick = false; - - defer if (!this.next_tick_pending and (needs_tick or - // this is evaluated _after_ this function call - vm.eventLoop().pending_tasks_count.value > 0)) - this.queueNextTick(); if (ctx.aborted) { ctx.finalize(); @@ -1514,7 +1503,6 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { }, } wait_for_promise = true; - needs_tick = true; // I don't think this case should happen // But I'm uncertain } else if (ctx.response_jsvalue.asInternalPromise()) |promise| { @@ -1530,7 +1518,6 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { }, } wait_for_promise = true; - needs_tick = true; } if (wait_for_promise) { |