mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
Merge pull request #829 from lightpanda-io/pumpmessageloop
Some checks failed
e2e-test / zig build release (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 / zig build dev (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
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
Some checks failed
e2e-test / zig build release (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 / zig build dev (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
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
add pump message loop calls
This commit is contained in:
@@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator;
|
|||||||
const log = @import("log.zig");
|
const log = @import("log.zig");
|
||||||
const Loop = @import("runtime/loop.zig").Loop;
|
const Loop = @import("runtime/loop.zig").Loop;
|
||||||
const http = @import("http/client.zig");
|
const http = @import("http/client.zig");
|
||||||
|
const Platform = @import("runtime/js.zig").Platform;
|
||||||
|
|
||||||
const Telemetry = @import("telemetry/telemetry.zig").Telemetry;
|
const Telemetry = @import("telemetry/telemetry.zig").Telemetry;
|
||||||
const Notification = @import("notification.zig").Notification;
|
const Notification = @import("notification.zig").Notification;
|
||||||
@@ -13,6 +14,7 @@ const Notification = @import("notification.zig").Notification;
|
|||||||
pub const App = struct {
|
pub const App = struct {
|
||||||
loop: *Loop,
|
loop: *Loop,
|
||||||
config: Config,
|
config: Config,
|
||||||
|
platform: ?*const Platform,
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
telemetry: Telemetry,
|
telemetry: Telemetry,
|
||||||
http_client: http.Client,
|
http_client: http.Client,
|
||||||
@@ -28,6 +30,7 @@ pub const App = struct {
|
|||||||
|
|
||||||
pub const Config = struct {
|
pub const Config = struct {
|
||||||
run_mode: RunMode,
|
run_mode: RunMode,
|
||||||
|
platform: ?*const Platform = null,
|
||||||
tls_verify_host: bool = true,
|
tls_verify_host: bool = true,
|
||||||
http_proxy: ?std.Uri = null,
|
http_proxy: ?std.Uri = null,
|
||||||
proxy_type: ?http.ProxyType = null,
|
proxy_type: ?http.ProxyType = null,
|
||||||
@@ -53,6 +56,7 @@ pub const App = struct {
|
|||||||
.loop = loop,
|
.loop = loop,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.telemetry = undefined,
|
.telemetry = undefined,
|
||||||
|
.platform = config.platform,
|
||||||
.app_dir_path = app_dir_path,
|
.app_dir_path = app_dir_path,
|
||||||
.notification = notification,
|
.notification = notification,
|
||||||
.http_client = try http.Client.init(allocator, loop, .{
|
.http_client = try http.Client.init(allocator, loop, .{
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ const App = @import("../app.zig").App;
|
|||||||
const Session = @import("session.zig").Session;
|
const Session = @import("session.zig").Session;
|
||||||
const Notification = @import("../notification.zig").Notification;
|
const Notification = @import("../notification.zig").Notification;
|
||||||
|
|
||||||
|
const log = @import("../log.zig");
|
||||||
|
|
||||||
const http = @import("../http/client.zig");
|
const http = @import("../http/client.zig");
|
||||||
|
|
||||||
// Browser is an instance of the browser.
|
// Browser is an instance of the browser.
|
||||||
@@ -47,7 +49,7 @@ pub const Browser = struct {
|
|||||||
pub fn init(app: *App) !Browser {
|
pub fn init(app: *App) !Browser {
|
||||||
const allocator = app.allocator;
|
const allocator = app.allocator;
|
||||||
|
|
||||||
const env = try Env.init(allocator, .{});
|
const env = try Env.init(allocator, app.platform, .{});
|
||||||
errdefer env.deinit();
|
errdefer env.deinit();
|
||||||
|
|
||||||
const notification = try Notification.init(allocator, app.notification);
|
const notification = try Notification.init(allocator, app.notification);
|
||||||
@@ -95,7 +97,14 @@ pub const Browser = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn runMicrotasks(self: *const Browser) void {
|
pub fn runMicrotasks(self: *const Browser) void {
|
||||||
return self.env.runMicrotasks();
|
self.env.runMicrotasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn runMessageLoop(self: *const Browser) void {
|
||||||
|
while (self.env.pumpMessageLoop()) {
|
||||||
|
log.debug(.browser, "pumpMessageLoop", .{});
|
||||||
|
}
|
||||||
|
self.env.runIdleTasks();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,10 @@ pub const Page = struct {
|
|||||||
|
|
||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
|
|
||||||
|
// run v8 micro tasks
|
||||||
microtask_node: Loop.CallbackNode,
|
microtask_node: Loop.CallbackNode,
|
||||||
|
// run v8 pump message loop and idle tasks
|
||||||
|
messageloop_node: Loop.CallbackNode,
|
||||||
|
|
||||||
keydown_event_node: parser.EventNode,
|
keydown_event_node: parser.EventNode,
|
||||||
window_clicked_event_node: parser.EventNode,
|
window_clicked_event_node: parser.EventNode,
|
||||||
@@ -106,6 +109,7 @@ pub const Page = struct {
|
|||||||
.state_pool = &browser.state_pool,
|
.state_pool = &browser.state_pool,
|
||||||
.cookie_jar = &session.cookie_jar,
|
.cookie_jar = &session.cookie_jar,
|
||||||
.microtask_node = .{ .func = microtaskCallback },
|
.microtask_node = .{ .func = microtaskCallback },
|
||||||
|
.messageloop_node = .{ .func = messageLoopCallback },
|
||||||
.keydown_event_node = .{ .func = keydownCallback },
|
.keydown_event_node = .{ .func = keydownCallback },
|
||||||
.window_clicked_event_node = .{ .func = windowClicked },
|
.window_clicked_event_node = .{ .func = windowClicked },
|
||||||
.request_factory = browser.http_client.requestFactory(.{
|
.request_factory = browser.http_client.requestFactory(.{
|
||||||
@@ -119,6 +123,10 @@ pub const Page = struct {
|
|||||||
try polyfill.load(self.arena, self.main_context);
|
try polyfill.load(self.arena, self.main_context);
|
||||||
|
|
||||||
_ = try session.browser.app.loop.timeout(1 * std.time.ns_per_ms, &self.microtask_node);
|
_ = try session.browser.app.loop.timeout(1 * std.time.ns_per_ms, &self.microtask_node);
|
||||||
|
// message loop must run only non-test env
|
||||||
|
if (comptime !builtin.is_test) {
|
||||||
|
_ = try session.browser.app.loop.timeout(1 * std.time.ns_per_ms, &self.messageloop_node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn microtaskCallback(node: *Loop.CallbackNode, repeat_delay: *?u63) void {
|
fn microtaskCallback(node: *Loop.CallbackNode, repeat_delay: *?u63) void {
|
||||||
@@ -127,6 +135,12 @@ pub const Page = struct {
|
|||||||
repeat_delay.* = 1 * std.time.ns_per_ms;
|
repeat_delay.* = 1 * std.time.ns_per_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn messageLoopCallback(node: *Loop.CallbackNode, repeat_delay: *?u63) void {
|
||||||
|
const self: *Page = @fieldParentPtr("messageloop_node", node);
|
||||||
|
self.session.browser.runMessageLoop();
|
||||||
|
repeat_delay.* = 100 * std.time.ns_per_ms;
|
||||||
|
}
|
||||||
|
|
||||||
// dump writes the page content into the given file.
|
// dump writes the page content into the given file.
|
||||||
pub fn dump(self: *const Page, out: std.fs.File) !void {
|
pub fn dump(self: *const Page, out: std.fs.File) !void {
|
||||||
if (self.raw_data) |raw_data| {
|
if (self.raw_data) |raw_data| {
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ fn run(alloc: Allocator) !void {
|
|||||||
|
|
||||||
var app = try App.init(alloc, .{
|
var app = try App.init(alloc, .{
|
||||||
.run_mode = args.mode,
|
.run_mode = args.mode,
|
||||||
|
.platform = &platform,
|
||||||
.http_proxy = args.httpProxy(),
|
.http_proxy = args.httpProxy(),
|
||||||
.proxy_type = args.proxyType(),
|
.proxy_type = args.proxyType(),
|
||||||
.proxy_auth = args.proxyAuth(),
|
.proxy_auth = args.proxyAuth(),
|
||||||
@@ -602,7 +603,7 @@ test "tests:beforeAll" {
|
|||||||
log.opts.format = .logfmt;
|
log.opts.format = .logfmt;
|
||||||
|
|
||||||
test_wg.startMany(3);
|
test_wg.startMany(3);
|
||||||
_ = try Platform.init();
|
const platform = try Platform.init();
|
||||||
|
|
||||||
{
|
{
|
||||||
const address = try std.net.Address.parseIp("127.0.0.1", 9582);
|
const address = try std.net.Address.parseIp("127.0.0.1", 9582);
|
||||||
@@ -618,7 +619,7 @@ test "tests:beforeAll" {
|
|||||||
|
|
||||||
{
|
{
|
||||||
const address = try std.net.Address.parseIp("127.0.0.1", 9583);
|
const address = try std.net.Address.parseIp("127.0.0.1", 9583);
|
||||||
const thread = try std.Thread.spawn(.{}, serveCDP, .{address});
|
const thread = try std.Thread.spawn(.{}, serveCDP, .{ address, &platform });
|
||||||
thread.detach();
|
thread.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -800,11 +801,12 @@ fn serveHTTPS(address: std.net.Address) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serveCDP(address: std.net.Address) !void {
|
fn serveCDP(address: std.net.Address, platform: *const Platform) !void {
|
||||||
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
|
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
|
||||||
var app = try App.init(gpa.allocator(), .{
|
var app = try App.init(gpa.allocator(), .{
|
||||||
.run_mode = .serve,
|
.run_mode = .serve,
|
||||||
.tls_verify_host = false,
|
.tls_verify_host = false,
|
||||||
|
.platform = platform,
|
||||||
});
|
});
|
||||||
defer app.deinit();
|
defer app.deinit();
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,13 @@ pub fn main() !void {
|
|||||||
defer _ = test_arena.reset(.{ .retain_capacity = {} });
|
defer _ = test_arena.reset(.{ .retain_capacity = {} });
|
||||||
|
|
||||||
var err_out: ?[]const u8 = null;
|
var err_out: ?[]const u8 = null;
|
||||||
const result = run(test_arena.allocator(), test_file, &loader, &err_out) catch |err| blk: {
|
const result = run(
|
||||||
|
test_arena.allocator(),
|
||||||
|
&platform,
|
||||||
|
test_file,
|
||||||
|
&loader,
|
||||||
|
&err_out,
|
||||||
|
) catch |err| blk: {
|
||||||
if (err_out == null) {
|
if (err_out == null) {
|
||||||
err_out = @errorName(err);
|
err_out = @errorName(err);
|
||||||
}
|
}
|
||||||
@@ -89,7 +95,13 @@ pub fn main() !void {
|
|||||||
try writer.finalize();
|
try writer.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(arena: Allocator, test_file: []const u8, loader: *FileLoader, err_out: *?[]const u8) !?[]const u8 {
|
fn run(
|
||||||
|
arena: Allocator,
|
||||||
|
platform: *const Platform,
|
||||||
|
test_file: []const u8,
|
||||||
|
loader: *FileLoader,
|
||||||
|
err_out: *?[]const u8,
|
||||||
|
) !?[]const u8 {
|
||||||
// document
|
// document
|
||||||
const html = blk: {
|
const html = blk: {
|
||||||
const full_path = try std.fs.path.join(arena, &.{ WPT_DIR, test_file });
|
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: *?
|
|||||||
var runner = try @import("testing.zig").jsRunner(arena, .{
|
var runner = try @import("testing.zig").jsRunner(arena, .{
|
||||||
.url = "http://127.0.0.1",
|
.url = "http://127.0.0.1",
|
||||||
.html = html,
|
.html = html,
|
||||||
|
.platform = platform,
|
||||||
});
|
});
|
||||||
defer runner.deinit();
|
defer runner.deinit();
|
||||||
|
|
||||||
|
|||||||
@@ -156,6 +156,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
|||||||
return struct {
|
return struct {
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
|
|
||||||
|
platform: ?*const Platform,
|
||||||
|
|
||||||
// the global isolate
|
// the global isolate
|
||||||
isolate: v8.Isolate,
|
isolate: v8.Isolate,
|
||||||
|
|
||||||
@@ -181,7 +183,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
|||||||
|
|
||||||
const Opts = struct {};
|
const Opts = struct {};
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, _: Opts) !*Self {
|
pub fn init(allocator: Allocator, platform: ?*const Platform, _: Opts) !*Self {
|
||||||
// var params = v8.initCreateParams();
|
// var params = v8.initCreateParams();
|
||||||
var params = try allocator.create(v8.CreateParams);
|
var params = try allocator.create(v8.CreateParams);
|
||||||
errdefer allocator.destroy(params);
|
errdefer allocator.destroy(params);
|
||||||
@@ -215,6 +217,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
|||||||
errdefer allocator.destroy(env);
|
errdefer allocator.destroy(env);
|
||||||
|
|
||||||
env.* = .{
|
env.* = .{
|
||||||
|
.platform = platform,
|
||||||
.isolate = isolate,
|
.isolate = isolate,
|
||||||
.templates = undefined,
|
.templates = undefined,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
@@ -270,6 +273,16 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
|||||||
self.isolate.performMicrotasksCheckpoint();
|
self.isolate.performMicrotasksCheckpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pumpMessageLoop(self: *const Self) bool {
|
||||||
|
// assume it's not-null.
|
||||||
|
return self.platform.?.inner.pumpMessageLoop(self.isolate, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn runIdleTasks(self: *const Self) void {
|
||||||
|
// assume it's not-null.
|
||||||
|
return self.platform.?.inner.runIdleTasks(self.isolate, 1);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn newExecutionWorld(self: *Self) !ExecutionWorld {
|
pub fn newExecutionWorld(self: *Self) !ExecutionWorld {
|
||||||
return .{
|
return .{
|
||||||
.env = self,
|
.env = self,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub fn Runner(comptime State: type, comptime Global: type, comptime types: anyty
|
|||||||
const self = try allocator.create(Self);
|
const self = try allocator.create(Self);
|
||||||
errdefer allocator.destroy(self);
|
errdefer allocator.destroy(self);
|
||||||
|
|
||||||
self.env = try Env.init(allocator, .{});
|
self.env = try Env.init(allocator, null, .{});
|
||||||
errdefer self.env.deinit();
|
errdefer self.env.deinit();
|
||||||
|
|
||||||
self.executor = try self.env.newExecutionWorld();
|
self.executor = try self.env.newExecutionWorld();
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
const Platform = @import("runtime/js.zig").Platform;
|
||||||
|
|
||||||
pub const allocator = std.testing.allocator;
|
pub const allocator = std.testing.allocator;
|
||||||
pub const expectError = std.testing.expectError;
|
pub const expectError = std.testing.expectError;
|
||||||
pub const expect = std.testing.expect;
|
pub const expect = std.testing.expect;
|
||||||
@@ -383,6 +385,7 @@ pub const JsRunner = struct {
|
|||||||
var app = try App.init(alloc, .{
|
var app = try App.init(alloc, .{
|
||||||
.run_mode = .serve,
|
.run_mode = .serve,
|
||||||
.tls_verify_host = false,
|
.tls_verify_host = false,
|
||||||
|
.platform = opts.platform,
|
||||||
});
|
});
|
||||||
errdefer app.deinit();
|
errdefer app.deinit();
|
||||||
|
|
||||||
@@ -474,6 +477,7 @@ pub const JsRunner = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const RunnerOpts = struct {
|
const RunnerOpts = struct {
|
||||||
|
platform: ?*const Platform = null,
|
||||||
url: []const u8 = "https://lightpanda.io/opensource-browser/",
|
url: []const u8 = "https://lightpanda.io/opensource-browser/",
|
||||||
html: []const u8 =
|
html: []const u8 =
|
||||||
\\ <div id="content">
|
\\ <div id="content">
|
||||||
|
|||||||
Reference in New Issue
Block a user