mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-28 22:53:28 +00:00
Optimize intervals, and make sure they're probably cleaned up.
A loop interval will no longer stop the loop from returning from `run`, and no longer requires mutating event_nb on each iteration. Re-enable microtask loop, which I accidentally stopped in a previous commit.
This commit is contained in:
@@ -267,7 +267,7 @@ pub const Page = struct {
|
||||
// load polyfills
|
||||
try polyfill.load(self.arena, self.scope);
|
||||
|
||||
// _ = 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);
|
||||
}
|
||||
|
||||
fn microtaskCallback(node: *Loop.CallbackNode, repeat_delay: *?u63) void {
|
||||
|
||||
@@ -41,6 +41,9 @@ pub const Loop = struct {
|
||||
// event are finished.
|
||||
events_nb: usize,
|
||||
|
||||
// Used to stop repeating timeouts when loop.run is called.
|
||||
stopping: bool,
|
||||
|
||||
// ctx_id is incremented each time the loop is reset.
|
||||
// All callbacks store an initial ctx_id and compare before execution.
|
||||
// If a ctx is outdated, the callback is ignored.
|
||||
@@ -62,11 +65,12 @@ pub const Loop = struct {
|
||||
pub const ConnectError = IO.ConnectError;
|
||||
|
||||
pub fn init(alloc: std.mem.Allocator) !Self {
|
||||
return Self{
|
||||
return .{
|
||||
.alloc = alloc,
|
||||
.cancelled = .{},
|
||||
.io = try IO.init(32, 0),
|
||||
.events_nb = 0,
|
||||
.stopping = false,
|
||||
.timeout_pool = MemoryPool(ContextTimeout).init(alloc),
|
||||
.event_callback_pool = MemoryPool(EventCallbackContext).init(alloc),
|
||||
};
|
||||
@@ -98,6 +102,10 @@ pub const Loop = struct {
|
||||
// Note that I/O events callbacks might register more I/O events
|
||||
// on the go when they are executed (ie. nested I/O events).
|
||||
pub fn run(self: *Self) !void {
|
||||
// stop repeating / interval timeouts from re-registering
|
||||
self.stopping = true;
|
||||
defer self.stopping = false;
|
||||
|
||||
while (self.eventsNb() > 0) {
|
||||
try self.io.run_for_ns(10 * std.time.ns_per_ms);
|
||||
// at each iteration we might have new events registred by previous callbacks
|
||||
@@ -134,6 +142,7 @@ pub const Loop = struct {
|
||||
const ContextTimeout = struct {
|
||||
loop: *Self,
|
||||
ctx_id: u32,
|
||||
initial: bool = true,
|
||||
callback_node: ?*CallbackNode,
|
||||
};
|
||||
|
||||
@@ -145,8 +154,11 @@ pub const Loop = struct {
|
||||
var repeating = false;
|
||||
const loop = ctx.loop;
|
||||
|
||||
defer {
|
||||
if (ctx.initial) {
|
||||
loop.removeEvent();
|
||||
}
|
||||
|
||||
defer {
|
||||
if (repeating == false) {
|
||||
loop.timeout_pool.destroy(ctx);
|
||||
loop.alloc.destroy(completion);
|
||||
@@ -174,10 +186,13 @@ pub const Loop = struct {
|
||||
if (ctx.callback_node) |cn| {
|
||||
var repeat_in: ?u63 = null;
|
||||
cn.func(cn, &repeat_in);
|
||||
if (repeat_in) |r| {
|
||||
// prevents our context and completion from being cleaned up
|
||||
repeating = true;
|
||||
loop.scheduleTimeout(r, ctx, completion);
|
||||
if (loop.stopping == false) {
|
||||
if (repeat_in) |r| {
|
||||
// prevents our context and completion from being cleaned up
|
||||
repeating = true;
|
||||
ctx.initial = false;
|
||||
loop.scheduleTimeout(r, ctx, completion);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,12 +210,12 @@ pub const Loop = struct {
|
||||
.callback_node = callback_node,
|
||||
};
|
||||
|
||||
self.addEvent();
|
||||
self.scheduleTimeout(nanoseconds, ctx, completion);
|
||||
return @intFromPtr(completion);
|
||||
}
|
||||
|
||||
fn scheduleTimeout(self: *Self, nanoseconds: u63, ctx: *ContextTimeout, completion: *Completion) void {
|
||||
self.addEvent();
|
||||
self.io.timeout(*ContextTimeout, ctx, timeoutCallback, completion, nanoseconds);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user