mirror of
https://github.com/RGBCube/serenity
synced 2025-07-10 06:27:35 +00:00
LibWeb+Browser+Ladybird: Use JS::SafeFunction for EventLoop callbacks
This automatically protects captured objects from being GC'd before the callback runs.
This commit is contained in:
parent
892470a912
commit
6d93e03211
11 changed files with 19 additions and 19 deletions
|
@ -18,13 +18,13 @@ namespace Ladybird {
|
||||||
EventLoopPluginQt::EventLoopPluginQt() = default;
|
EventLoopPluginQt::EventLoopPluginQt() = default;
|
||||||
EventLoopPluginQt::~EventLoopPluginQt() = default;
|
EventLoopPluginQt::~EventLoopPluginQt() = default;
|
||||||
|
|
||||||
void EventLoopPluginQt::spin_until(Function<bool()> goal_condition)
|
void EventLoopPluginQt::spin_until(JS::SafeFunction<bool()> goal_condition)
|
||||||
{
|
{
|
||||||
while (!goal_condition())
|
while (!goal_condition())
|
||||||
QCoreApplication::processEvents(QEventLoop::ProcessEventsFlag::AllEvents | QEventLoop::ProcessEventsFlag::WaitForMoreEvents);
|
QCoreApplication::processEvents(QEventLoop::ProcessEventsFlag::AllEvents | QEventLoop::ProcessEventsFlag::WaitForMoreEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventLoopPluginQt::deferred_invoke(Function<void()> function)
|
void EventLoopPluginQt::deferred_invoke(JS::SafeFunction<void()> function)
|
||||||
{
|
{
|
||||||
VERIFY(function);
|
VERIFY(function);
|
||||||
QTimer::singleShot(0, [function = move(function)] {
|
QTimer::singleShot(0, [function = move(function)] {
|
||||||
|
|
|
@ -15,8 +15,8 @@ public:
|
||||||
EventLoopPluginQt();
|
EventLoopPluginQt();
|
||||||
virtual ~EventLoopPluginQt() override;
|
virtual ~EventLoopPluginQt() override;
|
||||||
|
|
||||||
virtual void spin_until(Function<bool()> goal_condition) override;
|
virtual void spin_until(JS::SafeFunction<bool()> goal_condition) override;
|
||||||
virtual void deferred_invoke(Function<void()>) override;
|
virtual void deferred_invoke(JS::SafeFunction<void()>) override;
|
||||||
virtual NonnullRefPtr<Web::Platform::Timer> create_timer() override;
|
virtual NonnullRefPtr<Web::Platform::Timer> create_timer() override;
|
||||||
virtual void quit() override;
|
virtual void quit() override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
struct CustomData {
|
struct CustomData {
|
||||||
virtual ~CustomData() = default;
|
virtual ~CustomData() = default;
|
||||||
|
|
||||||
virtual void spin_event_loop_until(Function<bool()> goal_condition) = 0;
|
virtual void spin_event_loop_until(JS::SafeFunction<bool()> goal_condition) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ErrorOr<NonnullRefPtr<VM>> create(OwnPtr<CustomData> = {});
|
static ErrorOr<NonnullRefPtr<VM>> create(OwnPtr<CustomData> = {});
|
||||||
|
|
|
@ -499,7 +499,7 @@ NonnullOwnPtr<JS::ExecutionContext> create_a_new_javascript_realm(JS::VM& vm, Fu
|
||||||
return realm_execution_context;
|
return realm_execution_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebEngineCustomData::spin_event_loop_until(Function<bool()> goal_condition)
|
void WebEngineCustomData::spin_event_loop_until(JS::SafeFunction<bool()> goal_condition)
|
||||||
{
|
{
|
||||||
Platform::EventLoopPlugin::the().spin_until(move(goal_condition));
|
Platform::EventLoopPlugin::the().spin_until(move(goal_condition));
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct CustomElementReactionsStack {
|
||||||
struct WebEngineCustomData final : public JS::VM::CustomData {
|
struct WebEngineCustomData final : public JS::VM::CustomData {
|
||||||
virtual ~WebEngineCustomData() override = default;
|
virtual ~WebEngineCustomData() override = default;
|
||||||
|
|
||||||
virtual void spin_event_loop_until(Function<bool()> goal_condition) override;
|
virtual void spin_event_loop_until(JS::SafeFunction<bool()> goal_condition) override;
|
||||||
|
|
||||||
HTML::EventLoop event_loop;
|
HTML::EventLoop event_loop;
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,9 @@ void PendingResponse::run_callback()
|
||||||
{
|
{
|
||||||
VERIFY(m_callback);
|
VERIFY(m_callback);
|
||||||
VERIFY(m_response);
|
VERIFY(m_response);
|
||||||
Platform::EventLoopPlugin::the().deferred_invoke([strong_this = JS::make_handle(*this)] {
|
Platform::EventLoopPlugin::the().deferred_invoke([this] {
|
||||||
strong_this->m_callback(*strong_this->m_response);
|
m_callback(*m_response);
|
||||||
strong_this->m_request->remove_pending_response({}, *strong_this.ptr());
|
m_request->remove_pending_response({}, *this);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ EventLoop& main_thread_event_loop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/webappapis.html#spin-the-event-loop
|
// https://html.spec.whatwg.org/multipage/webappapis.html#spin-the-event-loop
|
||||||
void EventLoop::spin_until(Function<bool()> goal_condition)
|
void EventLoop::spin_until(JS::SafeFunction<bool()> goal_condition)
|
||||||
{
|
{
|
||||||
// FIXME: 1. Let task be the event loop's currently running task.
|
// FIXME: 1. Let task be the event loop's currently running task.
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
TaskQueue& microtask_queue() { return m_microtask_queue; }
|
TaskQueue& microtask_queue() { return m_microtask_queue; }
|
||||||
TaskQueue const& microtask_queue() const { return m_microtask_queue; }
|
TaskQueue const& microtask_queue() const { return m_microtask_queue; }
|
||||||
|
|
||||||
void spin_until(Function<bool()> goal_condition);
|
void spin_until(JS::SafeFunction<bool()> goal_condition);
|
||||||
void process();
|
void process();
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#termination-nesting-level
|
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#termination-nesting-level
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Forward.h>
|
#include <AK/Forward.h>
|
||||||
|
#include <LibJS/SafeFunction.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
|
|
||||||
namespace Web::Platform {
|
namespace Web::Platform {
|
||||||
|
@ -18,8 +19,8 @@ public:
|
||||||
|
|
||||||
virtual ~EventLoopPlugin();
|
virtual ~EventLoopPlugin();
|
||||||
|
|
||||||
virtual void spin_until(Function<bool()> goal_condition) = 0;
|
virtual void spin_until(JS::SafeFunction<bool()> goal_condition) = 0;
|
||||||
virtual void deferred_invoke(Function<void()>) = 0;
|
virtual void deferred_invoke(JS::SafeFunction<void()>) = 0;
|
||||||
virtual NonnullRefPtr<Timer> create_timer() = 0;
|
virtual NonnullRefPtr<Timer> create_timer() = 0;
|
||||||
virtual void quit() = 0;
|
virtual void quit() = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "EventLoopPluginSerenity.h"
|
#include "EventLoopPluginSerenity.h"
|
||||||
#include <AK/Function.h>
|
|
||||||
#include <AK/NonnullRefPtr.h>
|
#include <AK/NonnullRefPtr.h>
|
||||||
#include <LibCore/EventLoop.h>
|
#include <LibCore/EventLoop.h>
|
||||||
#include <LibWeb/Platform/TimerSerenity.h>
|
#include <LibWeb/Platform/TimerSerenity.h>
|
||||||
|
@ -15,12 +14,12 @@ namespace Web::Platform {
|
||||||
EventLoopPluginSerenity::EventLoopPluginSerenity() = default;
|
EventLoopPluginSerenity::EventLoopPluginSerenity() = default;
|
||||||
EventLoopPluginSerenity::~EventLoopPluginSerenity() = default;
|
EventLoopPluginSerenity::~EventLoopPluginSerenity() = default;
|
||||||
|
|
||||||
void EventLoopPluginSerenity::spin_until(Function<bool()> goal_condition)
|
void EventLoopPluginSerenity::spin_until(JS::SafeFunction<bool()> goal_condition)
|
||||||
{
|
{
|
||||||
Core::EventLoop::current().spin_until(move(goal_condition));
|
Core::EventLoop::current().spin_until(move(goal_condition));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventLoopPluginSerenity::deferred_invoke(Function<void()> function)
|
void EventLoopPluginSerenity::deferred_invoke(JS::SafeFunction<void()> function)
|
||||||
{
|
{
|
||||||
VERIFY(function);
|
VERIFY(function);
|
||||||
Core::deferred_invoke(move(function));
|
Core::deferred_invoke(move(function));
|
||||||
|
|
|
@ -15,8 +15,8 @@ public:
|
||||||
EventLoopPluginSerenity();
|
EventLoopPluginSerenity();
|
||||||
virtual ~EventLoopPluginSerenity() override;
|
virtual ~EventLoopPluginSerenity() override;
|
||||||
|
|
||||||
virtual void spin_until(Function<bool()> goal_condition) override;
|
virtual void spin_until(JS::SafeFunction<bool()> goal_condition) override;
|
||||||
virtual void deferred_invoke(Function<void()>) override;
|
virtual void deferred_invoke(JS::SafeFunction<void()>) override;
|
||||||
virtual NonnullRefPtr<Timer> create_timer() override;
|
virtual NonnullRefPtr<Timer> create_timer() override;
|
||||||
virtual void quit() override;
|
virtual void quit() override;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue