mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
Merge pull request #802 from lightpanda-io/endless_loop_fix_and_dot_slash_stitch
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / puppeteer-perf (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 / puppeteer-perf (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
Don't allow timeouts to be registered when shutting down
This commit is contained in:
@@ -144,12 +144,12 @@ pub const Page = struct {
|
|||||||
return self.fetchData("module", src);
|
return self.fetchData("module", src);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait(self: *Page) !void {
|
pub fn wait(self: *Page, wait_ns: usize) !void {
|
||||||
var try_catch: Env.TryCatch = undefined;
|
var try_catch: Env.TryCatch = undefined;
|
||||||
try_catch.init(self.main_context);
|
try_catch.init(self.main_context);
|
||||||
defer try_catch.deinit();
|
defer try_catch.deinit();
|
||||||
|
|
||||||
try self.session.browser.app.loop.run();
|
try self.session.browser.app.loop.run(wait_ns);
|
||||||
|
|
||||||
if (try_catch.hasCaught() == false) {
|
if (try_catch.hasCaught() == false) {
|
||||||
log.debug(.browser, "page wait complete", .{});
|
log.debug(.browser, "page wait complete", .{});
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ fn run(alloc: Allocator) !void {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
try page.wait();
|
try page.wait(std.time.ns_per_s * 3);
|
||||||
|
|
||||||
// dump
|
// dump
|
||||||
if (opts.dump) {
|
if (opts.dump) {
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ fn run(arena: Allocator, test_file: []const u8, loader: *FileLoader, err_out: *?
|
|||||||
var try_catch: Env.TryCatch = undefined;
|
var try_catch: Env.TryCatch = undefined;
|
||||||
try_catch.init(runner.page.main_context);
|
try_catch.init(runner.page.main_context);
|
||||||
defer try_catch.deinit();
|
defer try_catch.deinit();
|
||||||
try runner.page.loop.run();
|
try runner.page.loop.run(std.time.ns_per_ms * 200);
|
||||||
|
|
||||||
if (try_catch.hasCaught()) {
|
if (try_catch.hasCaught()) {
|
||||||
err_out.* = (try try_catch.err(arena)) orelse "unknwon error";
|
err_out.* = (try try_catch.err(arena)) orelse "unknwon error";
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ const MemoryPool = std.heap.MemoryPool;
|
|||||||
const log = @import("../log.zig");
|
const log = @import("../log.zig");
|
||||||
pub const IO = @import("tigerbeetle-io").IO;
|
pub const IO = @import("tigerbeetle-io").IO;
|
||||||
|
|
||||||
|
const RUN_DURATION = 10 * std.time.ns_per_ms;
|
||||||
|
|
||||||
// SingleThreaded I/O Loop based on Tigerbeetle io_uring loop.
|
// SingleThreaded I/O Loop based on Tigerbeetle io_uring loop.
|
||||||
// On Linux it's using io_uring.
|
// On Linux it's using io_uring.
|
||||||
// On MacOS and Windows it's using kqueue/IOCP with a ring design.
|
// On MacOS and Windows it's using kqueue/IOCP with a ring design.
|
||||||
@@ -82,7 +84,7 @@ pub const Loop = struct {
|
|||||||
// run tail events. We do run the tail events to ensure all the
|
// run tail events. We do run the tail events to ensure all the
|
||||||
// contexts are correcly free.
|
// contexts are correcly free.
|
||||||
while (self.pending_network_count != 0 or self.pending_timeout_count != 0) {
|
while (self.pending_network_count != 0 or self.pending_timeout_count != 0) {
|
||||||
self.io.run_for_ns(std.time.ns_per_ms * 10) catch |err| {
|
self.io.run_for_ns(RUN_DURATION) catch |err| {
|
||||||
log.err(.loop, "deinit", .{ .err = err });
|
log.err(.loop, "deinit", .{ .err = err });
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@@ -102,12 +104,16 @@ pub const Loop = struct {
|
|||||||
// Stops when there is no more I/O events registered on the loop.
|
// Stops when there is no more I/O events registered on the loop.
|
||||||
// Note that I/O events callbacks might register more I/O events
|
// Note that I/O events callbacks might register more I/O events
|
||||||
// on the go when they are executed (ie. nested I/O events).
|
// on the go when they are executed (ie. nested I/O events).
|
||||||
pub fn run(self: *Self) !void {
|
pub fn run(self: *Self, wait_ns: usize) !void {
|
||||||
// stop repeating / interval timeouts from re-registering
|
// stop repeating / interval timeouts from re-registering
|
||||||
self.stopping = true;
|
self.stopping = true;
|
||||||
defer self.stopping = false;
|
defer self.stopping = false;
|
||||||
|
|
||||||
while (self.pending_network_count != 0 or self.pending_timeout_count != 0) {
|
const max_iterations = wait_ns / (RUN_DURATION);
|
||||||
|
for (0..max_iterations) |_| {
|
||||||
|
if (self.pending_network_count == 0 and self.pending_timeout_count == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
self.io.run_for_ns(std.time.ns_per_ms * 10) catch |err| {
|
self.io.run_for_ns(std.time.ns_per_ms * 10) catch |err| {
|
||||||
log.err(.loop, "deinit", .{ .err = err });
|
log.err(.loop, "deinit", .{ .err = err });
|
||||||
break;
|
break;
|
||||||
@@ -187,6 +193,11 @@ pub const Loop = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn timeout(self: *Self, nanoseconds: u63, callback_node: ?*CallbackNode) !usize {
|
pub fn timeout(self: *Self, nanoseconds: u63, callback_node: ?*CallbackNode) !usize {
|
||||||
|
if (self.stopping and nanoseconds > std.time.ns_per_ms * 500) {
|
||||||
|
// we're trying to shutdown, we probably don't want to wait for a new
|
||||||
|
// long timeout
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
const completion = try self.alloc.create(Completion);
|
const completion = try self.alloc.create(Completion);
|
||||||
errdefer self.alloc.destroy(completion);
|
errdefer self.alloc.destroy(completion);
|
||||||
completion.* = undefined;
|
completion.* = undefined;
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ pub const JsRunner = struct {
|
|||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
try self.page.loop.run();
|
try self.page.loop.run(std.time.ns_per_ms * 200);
|
||||||
@import("root").js_runner_duration += std.time.Instant.since(try std.time.Instant.now(), start);
|
@import("root").js_runner_duration += std.time.Instant.since(try std.time.Instant.now(), start);
|
||||||
|
|
||||||
if (case.@"1") |expected| {
|
if (case.@"1") |expected| {
|
||||||
|
|||||||
40
src/url.zig
40
src/url.zig
@@ -110,7 +110,13 @@ pub const URL = struct {
|
|||||||
}
|
}
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
if (src.len == 0) {
|
|
||||||
|
var normalized_src = if (std.mem.startsWith(u8, src, "/")) src[1..] else src;
|
||||||
|
while (std.mem.startsWith(u8, normalized_src, "./")) {
|
||||||
|
normalized_src = normalized_src[2..];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalized_src.len == 0) {
|
||||||
if (opts.alloc == .always) {
|
if (opts.alloc == .always) {
|
||||||
return allocator.dupe(u8, base);
|
return allocator.dupe(u8, base);
|
||||||
}
|
}
|
||||||
@@ -125,8 +131,6 @@ pub const URL = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalized_src = if (src[0] == '/') src[1..] else src;
|
|
||||||
|
|
||||||
if (std.mem.lastIndexOfScalar(u8, base[protocol_end..], '/')) |index| {
|
if (std.mem.lastIndexOfScalar(u8, base[protocol_end..], '/')) |index| {
|
||||||
const last_slash_pos = index + protocol_end;
|
const last_slash_pos = index + protocol_end;
|
||||||
if (last_slash_pos == base.len - 1) {
|
if (last_slash_pos == base.len - 1) {
|
||||||
@@ -216,41 +220,41 @@ test "URL: resolve size" {
|
|||||||
test "URL: Stitching Base & Src URLs (Basic)" {
|
test "URL: Stitching Base & Src URLs (Basic)" {
|
||||||
const allocator = testing.allocator;
|
const allocator = testing.allocator;
|
||||||
|
|
||||||
const base = "https://www.google.com/xyz/abc/123";
|
const base = "https://lightpanda.io/xyz/abc/123";
|
||||||
const src = "something.js";
|
const src = "something.js";
|
||||||
const result = try URL.stitch(allocator, src, base, .{});
|
const result = try URL.stitch(allocator, src, base, .{});
|
||||||
defer allocator.free(result);
|
defer allocator.free(result);
|
||||||
try testing.expectString("https://www.google.com/xyz/abc/something.js", result);
|
try testing.expectString("https://lightpanda.io/xyz/abc/something.js", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "URL: Stitching Base & Src URLs (Just Ending Slash)" {
|
test "URL: Stitching Base & Src URLs (Just Ending Slash)" {
|
||||||
const allocator = testing.allocator;
|
const allocator = testing.allocator;
|
||||||
|
|
||||||
const base = "https://www.google.com/";
|
const base = "https://lightpanda.io/";
|
||||||
const src = "something.js";
|
const src = "something.js";
|
||||||
const result = try URL.stitch(allocator, src, base, .{});
|
const result = try URL.stitch(allocator, src, base, .{});
|
||||||
defer allocator.free(result);
|
defer allocator.free(result);
|
||||||
try testing.expectString("https://www.google.com/something.js", result);
|
try testing.expectString("https://lightpanda.io/something.js", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "URL: Stitching Base & Src URLs with leading slash" {
|
test "URL: Stitching Base & Src URLs with leading slash" {
|
||||||
const allocator = testing.allocator;
|
const allocator = testing.allocator;
|
||||||
|
|
||||||
const base = "https://www.google.com/";
|
const base = "https://lightpanda.io/";
|
||||||
const src = "/something.js";
|
const src = "/something.js";
|
||||||
const result = try URL.stitch(allocator, src, base, .{});
|
const result = try URL.stitch(allocator, src, base, .{});
|
||||||
defer allocator.free(result);
|
defer allocator.free(result);
|
||||||
try testing.expectString("https://www.google.com/something.js", result);
|
try testing.expectString("https://lightpanda.io/something.js", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "URL: Stitching Base & Src URLs (No Ending Slash)" {
|
test "URL: Stitching Base & Src URLs (No Ending Slash)" {
|
||||||
const allocator = testing.allocator;
|
const allocator = testing.allocator;
|
||||||
|
|
||||||
const base = "https://www.google.com";
|
const base = "https://lightpanda.io";
|
||||||
const src = "something.js";
|
const src = "something.js";
|
||||||
const result = try URL.stitch(allocator, src, base, .{});
|
const result = try URL.stitch(allocator, src, base, .{});
|
||||||
defer allocator.free(result);
|
defer allocator.free(result);
|
||||||
try testing.expectString("https://www.google.com/something.js", result);
|
try testing.expectString("https://lightpanda.io/something.js", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "URL: Stiching Base & Src URLs (Both Local)" {
|
test "URL: Stiching Base & Src URLs (Both Local)" {
|
||||||
@@ -275,11 +279,21 @@ test "URL: Stiching src as full path" {
|
|||||||
test "URL: Stitching Base & Src URLs (empty src)" {
|
test "URL: Stitching Base & Src URLs (empty src)" {
|
||||||
const allocator = testing.allocator;
|
const allocator = testing.allocator;
|
||||||
|
|
||||||
const base = "https://www.google.com/xyz/abc/123";
|
const base = "https://lightpanda.io/xyz/abc/123";
|
||||||
const src = "";
|
const src = "";
|
||||||
const result = try URL.stitch(allocator, src, base, .{});
|
const result = try URL.stitch(allocator, src, base, .{});
|
||||||
defer allocator.free(result);
|
defer allocator.free(result);
|
||||||
try testing.expectString("https://www.google.com/xyz/abc/123", result);
|
try testing.expectString("https://lightpanda.io/xyz/abc/123", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "URL: Stitching dotslash" {
|
||||||
|
const allocator = testing.allocator;
|
||||||
|
|
||||||
|
const base = "https://lightpanda.io/hello/";
|
||||||
|
const src = "./something.js";
|
||||||
|
const result = try URL.stitch(allocator, src, base, .{});
|
||||||
|
defer allocator.free(result);
|
||||||
|
try testing.expectString("https://lightpanda.io/hello/something.js", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "URL: concatQueryString" {
|
test "URL: concatQueryString" {
|
||||||
|
|||||||
Reference in New Issue
Block a user