diff --git a/src/loop.zig b/src/loop.zig index 74368c1..4b4fbb7 100644 --- a/src/loop.zig +++ b/src/loop.zig @@ -33,8 +33,12 @@ const log = std.log.scoped(.loop); pub const SingleThreaded = struct { alloc: std.mem.Allocator, // TODO: unmanaged version ? io: IO, + + // both events_nb are used to track how many callbacks are to be called. + // We use these counters to wait until all the events are finished. js_events_nb: usize, zig_events_nb: usize, + cbk_error: bool = false, // js_ctx_id is incremented each time the loop is reset for JS. @@ -79,6 +83,12 @@ pub const SingleThreaded = struct { } pub fn deinit(self: *Self) void { + // first disable callbacks for existing events. + // We don't want a callback re-create a setTimeout, it could create an + // infinite loop on wait for events. + self.resetJS(); + self.resetZig(); + // run tail events. We do run the tail events to ensure all the // contexts are correcly free. while (self.eventsNb(.js) > 0 or self.eventsNb(.zig) > 0) { @@ -88,7 +98,7 @@ pub const SingleThreaded = struct { }; } if (comptime CANCEL_SUPPORTED) { - self.cancelAll(); + self.io.cancel_all(); } self.io.deinit(); self.cancel_pool.deinit(); @@ -138,9 +148,6 @@ pub const SingleThreaded = struct { fn eventsNb(self: *Self, comptime event: Event) usize { return @atomicLoad(usize, self.eventsPtr(event), .seq_cst); } - fn resetEvents(self: *Self, comptime event: Event) void { - @atomicStore(usize, self.eventsPtr(event), 0, .unordered); - } // JS callbacks APIs // ----------------- @@ -284,19 +291,17 @@ pub const SingleThreaded = struct { self.io.cancel_one(*ContextCancel, ctx, cancelCallback, completion, comp_cancel); } - fn cancelAll(self: *Self) void { - self.resetEvents(.js); - self.resetEvents(.zig); - self.io.cancel_all(); - } - // Reset all existing JS callbacks. + // The existing events will happen and their memory will be cleanup but the + // corresponding callbacks will not be called. pub fn resetJS(self: *Self) void { self.js_ctx_id += 1; self.cancelled.clearRetainingCapacity(); } // Reset all existing Zig callbacks. + // The existing events will happen and their memory will be cleanup but the + // corresponding callbacks will not be called. pub fn resetZig(self: *Self) void { self.zig_ctx_id += 1; }