@@ -33,8 +33,12 @@ const log = std.log.scoped(.loop);
3333pub const SingleThreaded = struct {
3434 alloc : std.mem.Allocator , // TODO: unmanaged version ?
3535 io : IO ,
36+
37+ // both events_nb are used to track how many callbacks are to be called.
38+ // We use these counters to wait until all the events are finished.
3639 js_events_nb : usize ,
3740 zig_events_nb : usize ,
41+
3842 cbk_error : bool = false ,
3943
4044 // js_ctx_id is incremented each time the loop is reset for JS.
@@ -79,6 +83,12 @@ pub const SingleThreaded = struct {
7983 }
8084
8185 pub fn deinit (self : * Self ) void {
86+ // first disable callbacks for existing events.
87+ // We don't want a callback re-create a setTimeout, it could create an
88+ // infinite loop on wait for events.
89+ self .resetJS ();
90+ self .resetZig ();
91+
8292 // run tail events. We do run the tail events to ensure all the
8393 // contexts are correcly free.
8494 while (self .eventsNb (.js ) > 0 or self .eventsNb (.zig ) > 0 ) {
@@ -88,7 +98,7 @@ pub const SingleThreaded = struct {
8898 };
8999 }
90100 if (comptime CANCEL_SUPPORTED ) {
91- self .cancelAll ();
101+ self .io . cancel_all ();
92102 }
93103 self .io .deinit ();
94104 self .cancel_pool .deinit ();
@@ -138,9 +148,6 @@ pub const SingleThreaded = struct {
138148 fn eventsNb (self : * Self , comptime event : Event ) usize {
139149 return @atomicLoad (usize , self .eventsPtr (event ), .seq_cst );
140150 }
141- fn resetEvents (self : * Self , comptime event : Event ) void {
142- @atomicStore (usize , self .eventsPtr (event ), 0 , .unordered );
143- }
144151
145152 // JS callbacks APIs
146153 // -----------------
@@ -284,19 +291,17 @@ pub const SingleThreaded = struct {
284291 self .io .cancel_one (* ContextCancel , ctx , cancelCallback , completion , comp_cancel );
285292 }
286293
287- fn cancelAll (self : * Self ) void {
288- self .resetEvents (.js );
289- self .resetEvents (.zig );
290- self .io .cancel_all ();
291- }
292-
293294 // Reset all existing JS callbacks.
295+ // The existing events will happen and their memory will be cleanup but the
296+ // corresponding callbacks will not be called.
294297 pub fn resetJS (self : * Self ) void {
295298 self .js_ctx_id += 1 ;
296299 self .cancelled .clearRetainingCapacity ();
297300 }
298301
299302 // Reset all existing Zig callbacks.
303+ // The existing events will happen and their memory will be cleanup but the
304+ // corresponding callbacks will not be called.
300305 pub fn resetZig (self : * Self ) void {
301306 self .zig_ctx_id += 1 ;
302307 }
0 commit comments