1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 23:47:45 +00:00

Ladybird: Allow posting events to the Qt event loop from other threads

Previously, a QTimer was used to start processing of our event queue in
the main Qt event loop. Unfortunately, QTimers are not thread-safe, and
disallow starting of a timer from a different thread than it was
created in.

Instead, use a dummy QObject to post a custom QEvent to the main loop
from whatever thread we like, and process our event queue when it is
received by our dummy object.
This commit is contained in:
Zaggy1024 2023-07-04 04:37:36 -05:00 committed by Andrew Kaster
parent 6131d879f7
commit 78e1defbfe
6 changed files with 72 additions and 7 deletions

View file

@ -6,16 +6,20 @@
#pragma once
#include <AK/Badge.h>
#include <AK/HashMap.h>
#include <AK/NonnullOwnPtr.h>
#include <AK/OwnPtr.h>
#include <LibCore/EventLoopImplementation.h>
#include <QEvent>
#include <QEventLoop>
#include <QSocketNotifier>
#include <QTimer>
namespace Ladybird {
class EventLoopImplementationQtEventTarget;
class EventLoopManagerQt final : public Core::EventLoopManager {
public:
EventLoopManagerQt();
@ -29,13 +33,28 @@ public:
virtual void unregister_notifier(Core::Notifier&) override;
virtual void did_post_event() override;
static bool event_target_received_event(Badge<EventLoopImplementationQtEventTarget>, QEvent* event);
// FIXME: These APIs only exist for obscure use-cases inside SerenityOS. Try to get rid of them.
virtual int register_signal(int, Function<void(int)>) override { return 0; }
virtual void unregister_signal(int) override { }
private:
QTimer m_process_core_events_timer;
NonnullOwnPtr<EventLoopImplementationQtEventTarget> m_main_thread_event_target;
};
class QtEventLoopManagerEvent final : public QEvent {
public:
static QEvent::Type process_event_queue_event_type()
{
static auto const type = static_cast<QEvent::Type>(QEvent::registerEventType());
return type;
}
QtEventLoopManagerEvent(QEvent::Type type)
: QEvent(type)
{
}
};
class EventLoopImplementationQt final : public Core::EventLoopImplementation {