diff --git a/src/browser/js/bridge.zig b/src/browser/js/bridge.zig index b58da3f9..27359f88 100644 --- a/src/browser/js/bridge.zig +++ b/src/browser/js/bridge.zig @@ -92,11 +92,11 @@ pub fn Builder(comptime T: type) type { return entries; } - pub fn finalizer(comptime func: *const fn (self: *T) void) Finalizer { + pub fn finalizer(comptime func: *const fn (self: *T, comptime shutdown: bool) void) Finalizer { return .{ .from_zig = struct { fn wrap(ptr: *anyopaque) void { - func(@ptrCast(@alignCast(ptr))); + func(@ptrCast(@alignCast(ptr)), true); } }.wrap, @@ -115,7 +115,7 @@ pub fn Builder(comptime T: type) type { if (!ctx.identity_map.contains(@intFromPtr(ptr))) { return; } - func(self); + func(self, false); ctx.release(ptr); } }.wrap, diff --git a/src/browser/webapi/net/XMLHttpRequest.zig b/src/browser/webapi/net/XMLHttpRequest.zig index a25bd6b8..85b961c5 100644 --- a/src/browser/webapi/net/XMLHttpRequest.zig +++ b/src/browser/webapi/net/XMLHttpRequest.zig @@ -90,9 +90,13 @@ pub fn init(page: *Page) !*XMLHttpRequest { }); } -pub fn deinit(self: *XMLHttpRequest) void { +pub fn deinit(self: *XMLHttpRequest, comptime shutdown: bool) void { if (self._transfer) |transfer| { - transfer.terminate(); + if (shutdown) { + transfer.terminate(); + } else { + transfer.abort(error.Abort); + } self._transfer = null; } self._page.releaseArena(self._arena); diff --git a/src/http/Client.zig b/src/http/Client.zig index 9614d218..14ff21c7 100644 --- a/src/http/Client.zig +++ b/src/http/Client.zig @@ -371,7 +371,7 @@ fn makeTransfer(self: *Client, req: Request) !*Transfer { return transfer; } -fn requestFailed(self: *Client, transfer: *Transfer, err: anyerror) void { +fn requestFailed(self: *Client, transfer: *Transfer, err: anyerror, comptime execute_callback: bool) void { // this shouldn't happen, we'll crash in debug mode. But in release, we'll // just noop this state. if (comptime IS_DEBUG) { @@ -390,7 +390,9 @@ fn requestFailed(self: *Client, transfer: *Transfer, err: anyerror) void { }); } - transfer.req.error_callback(transfer.ctx, err); + if (execute_callback) { + transfer.req.error_callback(transfer.ctx, err); + } } // Restrictive since it'll only work if there are no inflight requests. In some @@ -600,7 +602,7 @@ fn processMessages(self: *Client) !bool { if (!transfer._header_done_called) { const proceed = transfer.headerDoneCallback(easy) catch |err| { log.err(.http, "header_done_callback", .{ .err = err }); - self.requestFailed(transfer, err); + self.requestFailed(transfer, err, true); continue; }; if (!proceed) { @@ -611,7 +613,7 @@ fn processMessages(self: *Client) !bool { transfer.req.done_callback(transfer.ctx) catch |err| { // transfer isn't valid at this point, don't use it. log.err(.http, "done_callback", .{ .err = err }); - self.requestFailed(transfer, err); + self.requestFailed(transfer, err, true); continue; }; @@ -622,7 +624,7 @@ fn processMessages(self: *Client) !bool { } processed = true; } else |err| { - self.requestFailed(transfer, err); + self.requestFailed(transfer, err, true); } } return processed; @@ -972,7 +974,7 @@ pub const Transfer = struct { } pub fn abort(self: *Transfer, err: anyerror) void { - self.client.requestFailed(self, err); + self.client.requestFailed(self, err, true); if (self._handle != null) { self.client.endTransfer(self); } @@ -980,6 +982,7 @@ pub const Transfer = struct { } pub fn terminate(self: *Transfer) void { + self.client.requestFailed(self, error.Shutdown, false); if (self._handle != null) { self.client.endTransfer(self); }