Files
ladybird/Libraries/LibWeb/Platform/Timer.h
Andreas Kling d51d849943 LibWeb: Keep active platform timers alive during GC
Treat active Platform::Timer objects as event-loop roots so their GC
callbacks stay marked while the underlying Core::Timer can still fire.
Finalize unreachable timers by stopping the Core timer and dropping the
callback, preventing incremental sweep from leaving a timer with a raw
pointer to a swept GC::Function.
2026-05-10 10:58:11 +02:00

58 lines
1.4 KiB
C++

/*
* Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/NonnullRefPtr.h>
#include <LibCore/Forward.h>
#include <LibGC/CellAllocator.h>
#include <LibJS/Heap/Cell.h>
namespace Web::Platform {
class Timer : public JS::Cell {
GC_CELL(Timer, JS::Cell);
GC_DECLARE_ALLOCATOR(Timer);
public:
static GC::Ref<Timer> create(GC::Heap&);
static GC::Ref<Timer> create_repeating(GC::Heap&, int interval_ms, GC::Ptr<GC::Function<void()>> timeout_handler);
static GC::Ref<Timer> create_single_shot(GC::Heap&, int interval_ms, GC::Ptr<GC::Function<void()>> timeout_handler);
static constexpr bool OVERRIDES_MUST_SURVIVE_GARBAGE_COLLECTION = true;
static constexpr bool OVERRIDES_FINALIZE = true;
virtual ~Timer();
virtual void finalize() override;
virtual bool must_survive_garbage_collection() const override;
void start();
void start(int interval_ms);
void restart();
void restart(int interval_ms);
void stop();
void set_active(bool);
bool is_active() const;
int interval() const;
void set_interval(int interval_ms);
bool is_single_shot() const;
void set_single_shot(bool);
GC::Ptr<GC::Function<void()>> on_timeout;
private:
Timer();
virtual void visit_edges(JS::Cell::Visitor&) override;
NonnullRefPtr<Core::Timer> m_timer;
};
}