mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-19 09:17:38 +03:00
LibWeb: Schedule HTML::EventLoop processing when there are queued tasks
Since we can't simply give HTML::EventLoop control of the whole program, we have to integrate with Core::EventLoop. We do this by having a single-shot 0ms Core::Timer that we start when a task is added to the queue, and restart after processing the queue and there are still tasks in the queue.
This commit is contained in:
parent
e0c7f8dafa
commit
909e522cf7
Notes:
sideshowbarker
2024-07-18 04:24:27 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/909e522cf70
@ -65,6 +65,7 @@ class CanvasRenderingContext2D;
|
||||
class CloseEvent;
|
||||
class DOMParser;
|
||||
struct EventHandler;
|
||||
class EventLoop;
|
||||
class HTMLAnchorElement;
|
||||
class HTMLAreaElement;
|
||||
class HTMLAudioElement;
|
||||
|
@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
||||
@ -11,6 +12,7 @@
|
||||
namespace Web::HTML {
|
||||
|
||||
EventLoop::EventLoop()
|
||||
: m_task_queue(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -18,6 +20,18 @@ EventLoop::~EventLoop()
|
||||
{
|
||||
}
|
||||
|
||||
void EventLoop::schedule()
|
||||
{
|
||||
if (!m_system_event_loop_timer) {
|
||||
m_system_event_loop_timer = Core::Timer::create_single_shot(0, [this] {
|
||||
process();
|
||||
});
|
||||
}
|
||||
|
||||
if (!m_system_event_loop_timer->is_active())
|
||||
m_system_event_loop_timer->restart();
|
||||
}
|
||||
|
||||
void EventLoop::set_vm(JS::VM& vm)
|
||||
{
|
||||
VERIFY(!m_vm);
|
||||
@ -66,6 +80,9 @@ void EventLoop::process()
|
||||
// 2. Let oldestTask be the first runnable task in taskQueue, and remove it from taskQueue.
|
||||
auto oldest_task = task_queue.take_first_runnable();
|
||||
|
||||
// FIXME: Figure out if we need to be here when there's no task.
|
||||
VERIFY(oldest_task);
|
||||
|
||||
// 3. Set the event loop's currently running task to oldestTask.
|
||||
m_currently_running_task = oldest_task.ptr();
|
||||
|
||||
@ -145,6 +162,10 @@ void EventLoop::process()
|
||||
// FIXME: 3. Update the rendering of that dedicated worker to reflect the current state.
|
||||
|
||||
// FIXME: 2. If there are no tasks in the event loop's task queues and the WorkerGlobalScope object's closing flag is true, then destroy the event loop, aborting these steps, resuming the run a worker steps described in the Web workers section below.
|
||||
|
||||
// If there are tasks in the queue, schedule a new round of processing. :^)
|
||||
if (!m_task_queue.is_empty())
|
||||
schedule();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibWeb/HTML/EventLoop/TaskQueue.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
@ -40,6 +42,8 @@ public:
|
||||
|
||||
void set_vm(JS::VM&);
|
||||
|
||||
void schedule();
|
||||
|
||||
private:
|
||||
Type m_type { Type::Window };
|
||||
|
||||
@ -49,6 +53,8 @@ private:
|
||||
Task* m_currently_running_task { nullptr };
|
||||
|
||||
JS::VM* m_vm { nullptr };
|
||||
|
||||
RefPtr<Core::Timer> m_system_event_loop_timer;
|
||||
};
|
||||
|
||||
EventLoop& main_thread_event_loop();
|
||||
|
@ -4,11 +4,13 @@
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
||||
#include <LibWeb/HTML/EventLoop/TaskQueue.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
TaskQueue::TaskQueue()
|
||||
TaskQueue::TaskQueue(HTML::EventLoop& event_loop)
|
||||
: m_event_loop(event_loop)
|
||||
{
|
||||
}
|
||||
|
||||
@ -19,6 +21,7 @@ TaskQueue::~TaskQueue()
|
||||
void TaskQueue::add(NonnullOwnPtr<Task> task)
|
||||
{
|
||||
m_tasks.enqueue(move(task));
|
||||
m_event_loop.schedule();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace Web::HTML {
|
||||
|
||||
class TaskQueue {
|
||||
public:
|
||||
TaskQueue();
|
||||
explicit TaskQueue(HTML::EventLoop&);
|
||||
~TaskQueue();
|
||||
|
||||
bool is_empty() const { return m_tasks.is_empty(); }
|
||||
@ -22,6 +22,8 @@ public:
|
||||
OwnPtr<HTML::Task> take_first_runnable() { return m_tasks.dequeue(); }
|
||||
|
||||
private:
|
||||
HTML::EventLoop& m_event_loop;
|
||||
|
||||
Queue<NonnullOwnPtr<HTML::Task>> m_tasks;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user