Skip to content

Commit a5dfe8a

Browse files
committed
handle multiple waiters for the same module
1 parent c52dce1 commit a5dfe8a

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

src/browser/ScriptManager.zig

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)