mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 07:03:29 +00:00
Merge pull request #1158 from lightpanda-io/concurrent-waitformodule
Some checks failed
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
e2e-test / zig build release (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
Some checks failed
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
e2e-test / zig build release (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
handle multiple waiters for the same module
This commit is contained in:
@@ -326,16 +326,31 @@ pub fn waitForModule(self: *ScriptManager, url: [:0]const u8) !GetResult {
|
|||||||
};
|
};
|
||||||
const sync = entry.value_ptr.*;
|
const sync = entry.value_ptr.*;
|
||||||
|
|
||||||
|
// We can have multiple scripts waiting for the same module in concurrency.
|
||||||
|
// We use the waiters to ensures only the last waiter deinit the resources.
|
||||||
|
sync.waiters += 1;
|
||||||
|
defer sync.waiters -= 1;
|
||||||
|
|
||||||
var client = self.client;
|
var client = self.client;
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (sync.state) {
|
switch (sync.state) {
|
||||||
.loading => {},
|
.loading => {},
|
||||||
.done => {
|
.done => {
|
||||||
|
if (sync.waiters == 1) {
|
||||||
// Our caller has its own higher level cache (caching the
|
// Our caller has its own higher level cache (caching the
|
||||||
// actual compiled module). There's no reason for us to keep this
|
// actual compiled module). There's no reason for us to keep
|
||||||
|
// this if we are the last waiter.
|
||||||
defer self.sync_module_pool.destroy(sync);
|
defer self.sync_module_pool.destroy(sync);
|
||||||
defer self.sync_modules.removeByPtr(entry.key_ptr);
|
defer self.sync_modules.removeByPtr(entry.key_ptr);
|
||||||
return .{
|
return .{
|
||||||
|
.shared = false,
|
||||||
|
.buffer = sync.buffer,
|
||||||
|
.buffer_pool = &self.buffer_pool,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.shared = true,
|
||||||
.buffer = sync.buffer,
|
.buffer = sync.buffer,
|
||||||
.buffer_pool = &self.buffer_pool,
|
.buffer_pool = &self.buffer_pool,
|
||||||
};
|
};
|
||||||
@@ -882,6 +897,8 @@ const SyncModule = struct {
|
|||||||
manager: *ScriptManager,
|
manager: *ScriptManager,
|
||||||
buffer: std.ArrayListUnmanaged(u8) = .{},
|
buffer: std.ArrayListUnmanaged(u8) = .{},
|
||||||
state: State = .loading,
|
state: State = .loading,
|
||||||
|
// number of waiters for the module.
|
||||||
|
waiters: u8 = 0,
|
||||||
|
|
||||||
const State = union(enum) {
|
const State = union(enum) {
|
||||||
done,
|
done,
|
||||||
@@ -997,6 +1014,7 @@ pub const AsyncModule = struct {
|
|||||||
var self: *AsyncModule = @ptrCast(@alignCast(ctx));
|
var self: *AsyncModule = @ptrCast(@alignCast(ctx));
|
||||||
defer self.manager.async_module_pool.destroy(self);
|
defer self.manager.async_module_pool.destroy(self);
|
||||||
self.cb(self.cb_data, .{
|
self.cb(self.cb_data, .{
|
||||||
|
.shared = false,
|
||||||
.buffer = self.buffer,
|
.buffer = self.buffer,
|
||||||
.buffer_pool = &self.manager.buffer_pool,
|
.buffer_pool = &self.manager.buffer_pool,
|
||||||
});
|
});
|
||||||
@@ -1020,8 +1038,13 @@ pub const AsyncModule = struct {
|
|||||||
pub const GetResult = struct {
|
pub const GetResult = struct {
|
||||||
buffer: std.ArrayListUnmanaged(u8),
|
buffer: std.ArrayListUnmanaged(u8),
|
||||||
buffer_pool: *BufferPool,
|
buffer_pool: *BufferPool,
|
||||||
|
shared: bool,
|
||||||
|
|
||||||
pub fn deinit(self: *GetResult) void {
|
pub fn deinit(self: *GetResult) void {
|
||||||
|
// if the result is shared, don't deinit.
|
||||||
|
if (self.shared) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
self.buffer_pool.release(self.buffer);
|
self.buffer_pool.release(self.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user