Skip to content

Commit f51ee7f

Browse files
Merge pull request #829 from lightpanda-io/pumpmessageloop
add pump message loop calls
2 parents e8866a6 + 9d1dc97 commit f51ee7f

File tree

8 files changed

+68
-9
lines changed

8 files changed

+68
-9
lines changed

src/app.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator;
44
const log = @import("log.zig");
55
const Loop = @import("runtime/loop.zig").Loop;
66
const http = @import("http/client.zig");
7+
const Platform = @import("runtime/js.zig").Platform;
78

89
const Telemetry = @import("telemetry/telemetry.zig").Telemetry;
910
const Notification = @import("notification.zig").Notification;
@@ -13,6 +14,7 @@ const Notification = @import("notification.zig").Notification;
1314
pub const App = struct {
1415
loop: *Loop,
1516
config: Config,
17+
platform: ?*const Platform,
1618
allocator: Allocator,
1719
telemetry: Telemetry,
1820
http_client: http.Client,
@@ -28,6 +30,7 @@ pub const App = struct {
2830

2931
pub const Config = struct {
3032
run_mode: RunMode,
33+
platform: ?*const Platform = null,
3134
tls_verify_host: bool = true,
3235
http_proxy: ?std.Uri = null,
3336
proxy_type: ?http.ProxyType = null,
@@ -53,6 +56,7 @@ pub const App = struct {
5356
.loop = loop,
5457
.allocator = allocator,
5558
.telemetry = undefined,
59+
.platform = config.platform,
5660
.app_dir_path = app_dir_path,
5761
.notification = notification,
5862
.http_client = try http.Client.init(allocator, loop, .{

src/browser/browser.zig

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ const App = @import("../app.zig").App;
2727
const Session = @import("session.zig").Session;
2828
const Notification = @import("../notification.zig").Notification;
2929

30+
const log = @import("../log.zig");
31+
3032
const http = @import("../http/client.zig");
3133

3234
// Browser is an instance of the browser.
@@ -47,7 +49,7 @@ pub const Browser = struct {
4749
pub fn init(app: *App) !Browser {
4850
const allocator = app.allocator;
4951

50-
const env = try Env.init(allocator, .{});
52+
const env = try Env.init(allocator, app.platform, .{});
5153
errdefer env.deinit();
5254

5355
const notification = try Notification.init(allocator, app.notification);
@@ -95,7 +97,14 @@ pub const Browser = struct {
9597
}
9698

9799
pub fn runMicrotasks(self: *const Browser) void {
98-
return self.env.runMicrotasks();
100+
self.env.runMicrotasks();
101+
}
102+
103+
pub fn runMessageLoop(self: *const Browser) void {
104+
while (self.env.pumpMessageLoop()) {
105+
log.debug(.browser, "pumpMessageLoop", .{});
106+
}
107+
self.env.runIdleTasks();
99108
}
100109
};
101110

src/browser/page.zig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ pub const Page = struct {
7878

7979
renderer: Renderer,
8080

81+
// run v8 micro tasks
8182
microtask_node: Loop.CallbackNode,
83+
// run v8 pump message loop and idle tasks
84+
messageloop_node: Loop.CallbackNode,
8285

8386
keydown_event_node: parser.EventNode,
8487
window_clicked_event_node: parser.EventNode,
@@ -106,6 +109,7 @@ pub const Page = struct {
106109
.state_pool = &browser.state_pool,
107110
.cookie_jar = &session.cookie_jar,
108111
.microtask_node = .{ .func = microtaskCallback },
112+
.messageloop_node = .{ .func = messageLoopCallback },
109113
.keydown_event_node = .{ .func = keydownCallback },
110114
.window_clicked_event_node = .{ .func = windowClicked },
111115
.request_factory = browser.http_client.requestFactory(.{
@@ -119,6 +123,10 @@ pub const Page = struct {
119123
try polyfill.load(self.arena, self.main_context);
120124

121125
_ = try session.browser.app.loop.timeout(1 * std.time.ns_per_ms, &self.microtask_node);
126+
// message loop must run only non-test env
127+
if (comptime !builtin.is_test) {
128+
_ = try session.browser.app.loop.timeout(1 * std.time.ns_per_ms, &self.messageloop_node);
129+
}
122130
}
123131

124132
fn microtaskCallback(node: *Loop.CallbackNode, repeat_delay: *?u63) void {
@@ -127,6 +135,12 @@ pub const Page = struct {
127135
repeat_delay.* = 1 * std.time.ns_per_ms;
128136
}
129137

138+
fn messageLoopCallback(node: *Loop.CallbackNode, repeat_delay: *?u63) void {
139+
const self: *Page = @fieldParentPtr("messageloop_node", node);
140+
self.session.browser.runMessageLoop();
141+
repeat_delay.* = 100 * std.time.ns_per_ms;
142+
}
143+
130144
// dump writes the page content into the given file.
131145
pub fn dump(self: *const Page, out: std.fs.File) !void {
132146
if (self.raw_data) |raw_data| {

src/main.zig

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ fn run(alloc: Allocator) !void {
8383

8484
var app = try App.init(alloc, .{
8585
.run_mode = args.mode,
86+
.platform = &platform,
8687
.http_proxy = args.httpProxy(),
8788
.proxy_type = args.proxyType(),
8889
.proxy_auth = args.proxyAuth(),
@@ -602,7 +603,7 @@ test "tests:beforeAll" {
602603
log.opts.format = .logfmt;
603604

604605
test_wg.startMany(3);
605-
_ = try Platform.init();
606+
const platform = try Platform.init();
606607

607608
{
608609
const address = try std.net.Address.parseIp("127.0.0.1", 9582);
@@ -618,7 +619,7 @@ test "tests:beforeAll" {
618619

619620
{
620621
const address = try std.net.Address.parseIp("127.0.0.1", 9583);
621-
const thread = try std.Thread.spawn(.{}, serveCDP, .{address});
622+
const thread = try std.Thread.spawn(.{}, serveCDP, .{ address, &platform });
622623
thread.detach();
623624
}
624625

@@ -800,11 +801,12 @@ fn serveHTTPS(address: std.net.Address) !void {
800801
}
801802
}
802803

803-
fn serveCDP(address: std.net.Address) !void {
804+
fn serveCDP(address: std.net.Address, platform: *const Platform) !void {
804805
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
805806
var app = try App.init(gpa.allocator(), .{
806807
.run_mode = .serve,
807808
.tls_verify_host = false,
809+
.platform = platform,
808810
});
809811
defer app.deinit();
810812

src/main_wpt.zig

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,13 @@ pub fn main() !void {
7070
defer _ = test_arena.reset(.{ .retain_capacity = {} });
7171

7272
var err_out: ?[]const u8 = null;
73-
const result = run(test_arena.allocator(), test_file, &loader, &err_out) catch |err| blk: {
73+
const result = run(
74+
test_arena.allocator(),
75+
&platform,
76+
test_file,
77+
&loader,
78+
&err_out,
79+
) catch |err| blk: {
7480
if (err_out == null) {
7581
err_out = @errorName(err);
7682
}
@@ -89,7 +95,13 @@ pub fn main() !void {
8995
try writer.finalize();
9096
}
9197

92-
fn run(arena: Allocator, test_file: []const u8, loader: *FileLoader, err_out: *?[]const u8) !?[]const u8 {
98+
fn run(
99+
arena: Allocator,
100+
platform: *const Platform,
101+
test_file: []const u8,
102+
loader: *FileLoader,
103+
err_out: *?[]const u8,
104+
) !?[]const u8 {
93105
// document
94106
const html = blk: {
95107
const full_path = try std.fs.path.join(arena, &.{ WPT_DIR, test_file });
@@ -110,6 +122,7 @@ fn run(arena: Allocator, test_file: []const u8, loader: *FileLoader, err_out: *?
110122
var runner = try @import("testing.zig").jsRunner(arena, .{
111123
.url = "http://127.0.0.1",
112124
.html = html,
125+
.platform = platform,
113126
});
114127
defer runner.deinit();
115128

src/runtime/js.zig

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
156156
return struct {
157157
allocator: Allocator,
158158

159+
platform: ?*const Platform,
160+
159161
// the global isolate
160162
isolate: v8.Isolate,
161163

@@ -181,7 +183,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
181183

182184
const Opts = struct {};
183185

184-
pub fn init(allocator: Allocator, _: Opts) !*Self {
186+
pub fn init(allocator: Allocator, platform: ?*const Platform, _: Opts) !*Self {
185187
// var params = v8.initCreateParams();
186188
var params = try allocator.create(v8.CreateParams);
187189
errdefer allocator.destroy(params);
@@ -215,6 +217,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
215217
errdefer allocator.destroy(env);
216218

217219
env.* = .{
220+
.platform = platform,
218221
.isolate = isolate,
219222
.templates = undefined,
220223
.allocator = allocator,
@@ -270,6 +273,16 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
270273
self.isolate.performMicrotasksCheckpoint();
271274
}
272275

276+
pub fn pumpMessageLoop(self: *const Self) bool {
277+
// assume it's not-null.
278+
return self.platform.?.inner.pumpMessageLoop(self.isolate, false);
279+
}
280+
281+
pub fn runIdleTasks(self: *const Self) void {
282+
// assume it's not-null.
283+
return self.platform.?.inner.runIdleTasks(self.isolate, 1);
284+
}
285+
273286
pub fn newExecutionWorld(self: *Self) !ExecutionWorld {
274287
return .{
275288
.env = self,

src/runtime/testing.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub fn Runner(comptime State: type, comptime Global: type, comptime types: anyty
4242
const self = try allocator.create(Self);
4343
errdefer allocator.destroy(self);
4444

45-
self.env = try Env.init(allocator, .{});
45+
self.env = try Env.init(allocator, null, .{});
4646
errdefer self.env.deinit();
4747

4848
self.executor = try self.env.newExecutionWorld();

src/testing.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
const std = @import("std");
2020
const Allocator = std.mem.Allocator;
2121

22+
const Platform = @import("runtime/js.zig").Platform;
23+
2224
pub const allocator = std.testing.allocator;
2325
pub const expectError = std.testing.expectError;
2426
pub const expect = std.testing.expect;
@@ -383,6 +385,7 @@ pub const JsRunner = struct {
383385
var app = try App.init(alloc, .{
384386
.run_mode = .serve,
385387
.tls_verify_host = false,
388+
.platform = opts.platform,
386389
});
387390
errdefer app.deinit();
388391

@@ -474,6 +477,7 @@ pub const JsRunner = struct {
474477
};
475478

476479
const RunnerOpts = struct {
480+
platform: ?*const Platform = null,
477481
url: []const u8 = "https://lightpanda.io/opensource-browser/",
478482
html: []const u8 =
479483
\\ <div id="content">

0 commit comments

Comments
 (0)