Skip to content

Commit 0ccd9e0

Browse files
authored
Merge pull request #716 from lightpanda-io/skip_long_timeouts
Skip long setTimeout/setInterval
2 parents bddb3f0 + 608e0a0 commit 0ccd9e0

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

src/browser/html/window.zig

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub const Window = struct {
5151
storage_shelf: ?*storage.Shelf = null,
5252

5353
// counter for having unique timer ids
54-
timer_id: u31 = 0,
54+
timer_id: u30 = 0,
5555
timers: std.AutoHashMapUnmanaged(u32, *TimerCallback) = .{},
5656

5757
crypto: Crypto = .{},
@@ -209,6 +209,15 @@ pub const Window = struct {
209209
}
210210

211211
fn createTimeout(self: *Window, cbk: Function, delay_: ?u32, page: *Page, comptime repeat: bool) !u32 {
212+
const delay = delay_ orelse 0;
213+
if (delay > 5000) {
214+
log.warn(.window, "long timeout ignored", .{ .delay = delay, .interval = repeat });
215+
// self.timer_id is u30, so the largest value we can generate is
216+
// 1_073_741_824. Returning 2_000_000_000 makes sure that clients
217+
// can call cancelTimer/cancelInterval without breaking anything.
218+
return 2_000_000_000;
219+
}
220+
212221
if (self.timers.count() > 512) {
213222
return error.TooManyTimeout;
214223
}
@@ -224,7 +233,7 @@ pub const Window = struct {
224233
}
225234
errdefer _ = self.timers.remove(timer_id);
226235

227-
const delay: u63 = @as(u63, (delay_ orelse 0)) * std.time.ns_per_ms;
236+
const delay_ms: u63 = @as(u63, delay) * std.time.ns_per_ms;
228237
const callback = try arena.create(TimerCallback);
229238

230239
callback.* = .{
@@ -233,9 +242,9 @@ pub const Window = struct {
233242
.window = self,
234243
.timer_id = timer_id,
235244
.node = .{ .func = TimerCallback.run },
236-
.repeat = if (repeat) delay else null,
245+
.repeat = if (repeat) delay_ms else null,
237246
};
238-
callback.loop_id = try page.loop.timeout(delay, &callback.node);
247+
callback.loop_id = try page.loop.timeout(delay_ms, &callback.node);
239248

240249
gop.value_ptr.* = callback;
241250
return timer_id;
@@ -345,4 +354,11 @@ test "Browser.HTML.Window" {
345354
.{ "innerHeight", "1" },
346355
.{ "innerWidth", "2" },
347356
}, .{});
357+
358+
// cancelAnimationFrame should be able to cancel a request with the given id
359+
try runner.testCases(&.{
360+
.{ "let longCall = false;", null },
361+
.{ "window.setTimeout(() => {longCall = true}, 5001);", null },
362+
.{ "longCall;", "false" },
363+
}, .{});
348364
}

0 commit comments

Comments
 (0)