Skip to content

Commit

Permalink
always deinit from main thread
Browse files Browse the repository at this point in the history
  • Loading branch information
cirospaciari committed Nov 26, 2024
1 parent be513e9 commit 4766923
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions src/bun.js/webcore/response.zig
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,18 @@ pub const Fetch = struct {
}
}

pub fn derefFromThread(this: *FetchTasklet) void {
const count = this.ref_count.fetchSub(1, .monotonic);
bun.debugAssert(count > 0);

if (count == 1) {
// this is really unlikely to happen, but can happen
// lets make sure that we always call deinit from main thread

this.javascript_vm.eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, FetchTasklet.deinit));
}
}

pub const HTTPRequestBody = union(enum) {
AnyBlob: AnyBlob,
Sendfile: http.Sendfile,
Expand Down Expand Up @@ -918,7 +930,7 @@ pub const Fetch = struct {
this.clearAbortSignal();
}

fn deinit(this: *FetchTasklet) void {
pub fn deinit(this: *FetchTasklet) void {
log("deinit", .{});

bun.assert(this.ref_count.load(.monotonic) == 0);
Expand Down Expand Up @@ -1785,9 +1797,11 @@ pub const Fetch = struct {
}

pub fn callback(task: *FetchTasklet, async_http: *http.AsyncHTTP, result: http.HTTPClientResult) void {
// at this point only this thread is accessing result to is no race condition
const is_done = !result.has_more;
// we are done with the http client so we can deref our side
defer if (is_done) task.deref();
// this is a atomic operation and will enqueue a task to deinit on the main thread
defer if (is_done) task.derefFromThread();

task.mutex.lock();
// we need to unlock before task.deref();
Expand Down

0 comments on commit 4766923

Please sign in to comment.