mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-02 22:55:23 +00:00
LibWeb: Make EventLoop, TaskQueue, and Task GC-allocated
...and use HeapFunction instead of SafeFunction for task steps. Since there is only one EventLoop per process, it lives as a global handle in the VM custom data. This makes it much easier to reason about lifetimes of tasks, task steps, and random stuff captured by them.
This commit is contained in:
@@ -15,7 +15,9 @@
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
class EventLoop {
|
||||
class EventLoop : public JS::Cell {
|
||||
JS_CELL(EventLoop, Cell);
|
||||
|
||||
public:
|
||||
enum class Type {
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#window-event-loop
|
||||
@@ -26,16 +28,15 @@ public:
|
||||
Worklet,
|
||||
};
|
||||
|
||||
EventLoop();
|
||||
~EventLoop();
|
||||
virtual ~EventLoop() override;
|
||||
|
||||
Type type() const { return m_type; }
|
||||
|
||||
TaskQueue& task_queue() { return m_task_queue; }
|
||||
TaskQueue const& task_queue() const { return m_task_queue; }
|
||||
TaskQueue& task_queue() { return *m_task_queue; }
|
||||
TaskQueue const& task_queue() const { return *m_task_queue; }
|
||||
|
||||
TaskQueue& microtask_queue() { return m_microtask_queue; }
|
||||
TaskQueue const& microtask_queue() const { return m_microtask_queue; }
|
||||
TaskQueue& microtask_queue() { return *m_microtask_queue; }
|
||||
TaskQueue const& microtask_queue() const { return *m_microtask_queue; }
|
||||
|
||||
void spin_until(JS::SafeFunction<bool()> goal_condition);
|
||||
void spin_processing_tasks_with_source_until(Task::Source, JS::SafeFunction<bool()> goal_condition);
|
||||
@@ -48,11 +49,6 @@ public:
|
||||
|
||||
Task const* currently_running_task() const { return m_currently_running_task; }
|
||||
|
||||
JS::VM& vm() { return *m_vm; }
|
||||
JS::VM const& vm() const { return *m_vm; }
|
||||
|
||||
void set_vm(JS::VM&);
|
||||
|
||||
void schedule();
|
||||
|
||||
void perform_a_microtask_checkpoint();
|
||||
@@ -79,21 +75,23 @@ public:
|
||||
bool execution_paused() const { return m_execution_paused; }
|
||||
|
||||
private:
|
||||
EventLoop();
|
||||
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
Type m_type { Type::Window };
|
||||
|
||||
TaskQueue m_task_queue;
|
||||
TaskQueue m_microtask_queue;
|
||||
JS::GCPtr<TaskQueue> m_task_queue;
|
||||
JS::GCPtr<TaskQueue> m_microtask_queue;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#currently-running-task
|
||||
Task* m_currently_running_task { nullptr };
|
||||
JS::GCPtr<Task> m_currently_running_task { nullptr };
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#last-render-opportunity-time
|
||||
double m_last_render_opportunity_time { 0 };
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#last-idle-period-start-time
|
||||
double m_last_idle_period_start_time { 0 };
|
||||
|
||||
JS::VM* m_vm { nullptr };
|
||||
|
||||
RefPtr<Platform::Timer> m_system_event_loop_timer;
|
||||
|
||||
// https://html.spec.whatwg.org/#performing-a-microtask-checkpoint
|
||||
@@ -102,7 +100,8 @@ private:
|
||||
Vector<WeakPtr<DOM::Document>> m_documents;
|
||||
|
||||
// Used to implement step 4 of "perform a microtask checkpoint".
|
||||
Vector<JS::NonnullGCPtr<EnvironmentSettingsObject>> m_related_environment_settings_objects;
|
||||
// NOTE: These are weak references! ESO registers and unregisters itself from the event loop manually.
|
||||
Vector<RawPtr<EnvironmentSettingsObject>> m_related_environment_settings_objects;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack
|
||||
Vector<JS::NonnullGCPtr<EnvironmentSettingsObject>> m_backup_incumbent_settings_object_stack;
|
||||
@@ -116,8 +115,8 @@ private:
|
||||
};
|
||||
|
||||
EventLoop& main_thread_event_loop();
|
||||
int queue_global_task(HTML::Task::Source, JS::Object&, JS::SafeFunction<void()> steps);
|
||||
void queue_a_microtask(DOM::Document const*, JS::SafeFunction<void()> steps);
|
||||
int queue_global_task(HTML::Task::Source, JS::Object&, Function<void()> steps);
|
||||
void queue_a_microtask(DOM::Document const*, Function<void()> steps);
|
||||
void perform_a_microtask_checkpoint();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user