@@ -326,15 +326,28 @@ pub fn waitForModule(self: *ScriptManager, url: [:0]const u8) !GetResult {
326326 };
327327 const sync = entry .value_ptr .* ;
328328
329+ // We can have multiple scripts waiting for the same module in concurrency.
330+ // We use the waiters to ensures only the last waiter deinit the resources.
331+ sync .waiters += 1 ;
332+ defer sync .waiters -= 1 ;
333+
329334 var client = self .client ;
330335 while (true ) {
331336 switch (sync .state ) {
332337 .loading = > {},
333338 .done = > {
334- // Our caller has its own higher level cache (caching the
335- // actual compiled module). There's no reason for us to keep this
336- defer self .sync_module_pool .destroy (sync );
337- defer self .sync_modules .removeByPtr (entry .key_ptr );
339+ if (sync .waiters == 1 ) {
340+ // Our caller has its own higher level cache (caching the
341+ // actual compiled module). There's no reason for us to keep
342+ // this if we are the last waiter.
343+ defer self .sync_module_pool .destroy (sync );
344+ defer self .sync_modules .removeByPtr (entry .key_ptr );
345+ return .{
346+ .buffer = sync .buffer ,
347+ .buffer_pool = & self .buffer_pool ,
348+ };
349+ }
350+
338351 return .{
339352 .buffer = sync .buffer ,
340353 .buffer_pool = & self .buffer_pool ,
@@ -882,6 +895,8 @@ const SyncModule = struct {
882895 manager : * ScriptManager ,
883896 buffer : std .ArrayListUnmanaged (u8 ) = .{},
884897 state : State = .loading ,
898+ // number of waiters for the module.
899+ waiters : u8 = 0 ,
885900
886901 const State = union (enum ) {
887902 done ,
0 commit comments