diff --git a/packages/bun-uws/src/HttpContext.h b/packages/bun-uws/src/HttpContext.h index 0081779bdaf08..f3d03f4b49c7a 100644 --- a/packages/bun-uws/src/HttpContext.h +++ b/packages/bun-uws/src/HttpContext.h @@ -348,11 +348,14 @@ struct HttpContext { return (us_socket_t *) asyncSocket; } - /* It is okay to uncork a closed socket and we need to */ - ((AsyncSocket *) s)->uncork(); + if (returnedSocket != nullptr) { + /* It is okay to uncork a closed socket, and we need to */ + ((AsyncSocket *) s)->uncork(); + return s; + } - /* We cannot return nullptr to the underlying stack in any case */ - return s; + // It's okay if this returns nullptr. + return static_cast(nullptr); }); /* Handle HTTP write out (note: SSL_read may trigger this spuriously, the app need to handle spurious calls) */ diff --git a/src/bun.js/api/bun/socket.zig b/src/bun.js/api/bun/socket.zig index a82786dac3a2f..7e983eb88fbfe 100644 --- a/src/bun.js/api/bun/socket.zig +++ b/src/bun.js/api/bun/socket.zig @@ -3643,12 +3643,12 @@ pub const DuplexUpgradeContext = struct { fn deinitInNextTick(this: *DuplexUpgradeContext) void { this.task_event = .Close; - this.vm.enqueueTask(JSC.Task.init(&this.task)); + this.vm.enqueueImmediateTask(JSC.Task.init(&this.task)); } fn startTLS(this: *DuplexUpgradeContext) void { this.task_event = .StartTLS; - this.vm.enqueueTask(JSC.Task.init(&this.task)); + this.vm.enqueueImmediateTask(JSC.Task.init(&this.task)); } fn deinit(this: *DuplexUpgradeContext) void { @@ -3758,7 +3758,7 @@ pub const WindowsNamedPipeListeningContext = if (Environment.isWindows) struct { fn deinitInNextTick(this: *WindowsNamedPipeListeningContext) void { bun.assert(this.task_event != .deinit); this.task_event = .deinit; - this.vm.enqueueTask(JSC.Task.init(&this.task)); + this.vm.enqueueImmediateTask(JSC.Task.init(&this.task)); } fn deinit(this: *WindowsNamedPipeListeningContext) void { @@ -3938,7 +3938,7 @@ pub const WindowsNamedPipeContext = if (Environment.isWindows) struct { fn deinitInNextTick(this: *WindowsNamedPipeContext) void { bun.assert(this.task_event != .deinit); this.task_event = .deinit; - this.vm.enqueueTask(JSC.Task.init(&this.task)); + this.vm.enqueueImmediateTask(JSC.Task.init(&this.task)); } fn create(globalThis: *JSC.JSGlobalObject, socket: SocketType) *WindowsNamedPipeContext { diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index be96467b2c866..07405f7300b1e 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -6548,7 +6548,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp }, .tracker = JSC.AsyncTaskTracker.init(vm), }); - event_loop.enqueueTask(JSC.Task.init(task)); + event_loop.enqueueImmediateTask(JSC.Task.init(task)); } if (this.pending_requests == 0 and this.listener == null and this.flags.has_js_deinited and !this.hasActiveWebSockets()) { if (this.config.websocket) |*ws| { @@ -6603,7 +6603,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp const task = bun.default_allocator.create(JSC.AnyTask) catch unreachable; task.* = JSC.AnyTask.New(ThisServer, deinit).init(this); - this.vm.enqueueTask(JSC.Task.init(task)); + this.vm.enqueueImmediateTask(JSC.Task.init(task)); } pub fn deinit(this: *ThisServer) void { @@ -7010,6 +7010,14 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp return; } + if (ctx.resp != null) { + if (resp.isClosed()) { + ctx.resp = null; + ctx.deref(); + return; + } + } + if (ctx.shouldRenderMissing()) { ctx.renderMissing(); return; diff --git a/src/deps/libuwsockets.cpp b/src/deps/libuwsockets.cpp index 5e0dd28eaf19a..7b6606a08d9eb 100644 --- a/src/deps/libuwsockets.cpp +++ b/src/deps/libuwsockets.cpp @@ -1619,6 +1619,10 @@ size_t uws_req_get_header(uws_req_t *res, const char *lower_case_header, } } +int uws_res_is_closed(int ssl, uws_res_r res) { + return us_socket_is_closed(ssl, (us_socket_t *)res); +} + __attribute__((callback (corker, ctx))) void uws_res_cork(int ssl, uws_res_r res, void *ctx, void (*corker)(void *ctx)) nonnull_fn_decl; diff --git a/src/deps/uws.zig b/src/deps/uws.zig index bbfd64d6a1fff..e3258e55b7802 100644 --- a/src/deps/uws.zig +++ b/src/deps/uws.zig @@ -3485,6 +3485,10 @@ pub fn NewApp(comptime ssl: bool) type { uws_res_end(ssl_flag, res.downcast(), data.ptr, data.len, close_connection); } + pub fn isClosed(res: *Response) bool { + return uws_res_is_closed(ssl_flag, res.downcast()) != 0; + } + pub fn tryEnd(res: *Response, data: []const u8, total: usize, close_: bool) bool { return uws_res_try_end(ssl_flag, res.downcast(), data.ptr, data.len, total, close_); } @@ -4427,3 +4431,4 @@ pub fn onThreadExit() void { extern fn uws_app_clear_routes(ssl_flag: c_int, app: *uws_app_t) void; extern fn uws_res_clear_corked_socket(loop: *Loop) void; +extern fn uws_res_is_closed(ssl_flag: c_int, res: *anyopaque) i32;