mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 09:51:57 -05:00
LibCore+Ladybird: Add EventLoopManager interface for persistent state
Things such as timers and notifiers aren't specific to one instance of Core::EventLoop, so let's not tie them down to EventLoopImplementation. Instead, move those APIs + signals & a few other things to a new EventLoopManager interface. EventLoopManager also knows how to create a new EventLoopImplementation object.
This commit is contained in:
parent
c21eb30a2b
commit
7b963e1e98
11 changed files with 177 additions and 118 deletions
|
@ -35,11 +35,6 @@ struct ThreadData {
|
|||
|
||||
EventLoopImplementationQt::EventLoopImplementationQt()
|
||||
{
|
||||
m_process_core_events_timer.setSingleShot(true);
|
||||
m_process_core_events_timer.setInterval(0);
|
||||
QObject::connect(&m_process_core_events_timer, &QTimer::timeout, [] {
|
||||
Core::ThreadEventQueue::current().process();
|
||||
});
|
||||
}
|
||||
|
||||
EventLoopImplementationQt::~EventLoopImplementationQt() = default;
|
||||
|
@ -79,7 +74,7 @@ void EventLoopImplementationQt::wake()
|
|||
m_event_loop.wakeUp();
|
||||
}
|
||||
|
||||
void EventLoopImplementationQt::deferred_invoke(Function<void()> function)
|
||||
void EventLoopManagerQt::deferred_invoke(Function<void()> function)
|
||||
{
|
||||
VERIFY(function);
|
||||
QTimer::singleShot(0, [function = move(function)] {
|
||||
|
@ -97,7 +92,7 @@ static void qt_timer_fired(int timer_id, Core::TimerShouldFireWhenNotVisible sho
|
|||
object.dispatch_event(event);
|
||||
}
|
||||
|
||||
int EventLoopImplementationQt::register_timer(Core::Object& object, int milliseconds, bool should_reload, Core::TimerShouldFireWhenNotVisible should_fire_when_not_visible)
|
||||
int EventLoopManagerQt::register_timer(Core::Object& object, int milliseconds, bool should_reload, Core::TimerShouldFireWhenNotVisible should_fire_when_not_visible)
|
||||
{
|
||||
auto& thread_data = ThreadData::the();
|
||||
auto timer = make<QTimer>();
|
||||
|
@ -116,7 +111,7 @@ int EventLoopImplementationQt::register_timer(Core::Object& object, int millisec
|
|||
return timer_id;
|
||||
}
|
||||
|
||||
bool EventLoopImplementationQt::unregister_timer(int timer_id)
|
||||
bool EventLoopManagerQt::unregister_timer(int timer_id)
|
||||
{
|
||||
auto& thread_data = ThreadData::the();
|
||||
thread_data.timer_id_allocator.deallocate(timer_id);
|
||||
|
@ -129,7 +124,7 @@ static void qt_notifier_activated(Core::Notifier& notifier)
|
|||
notifier.dispatch_event(event);
|
||||
}
|
||||
|
||||
void EventLoopImplementationQt::register_notifier(Core::Notifier& notifier)
|
||||
void EventLoopManagerQt::register_notifier(Core::Notifier& notifier)
|
||||
{
|
||||
QSocketNotifier::Type type;
|
||||
switch (notifier.type()) {
|
||||
|
@ -150,14 +145,34 @@ void EventLoopImplementationQt::register_notifier(Core::Notifier& notifier)
|
|||
ThreadData::the().notifiers.set(¬ifier, move(socket_notifier));
|
||||
}
|
||||
|
||||
void EventLoopImplementationQt::unregister_notifier(Core::Notifier& notifier)
|
||||
void EventLoopManagerQt::unregister_notifier(Core::Notifier& notifier)
|
||||
{
|
||||
ThreadData::the().notifiers.remove(¬ifier);
|
||||
}
|
||||
|
||||
void EventLoopImplementationQt::did_post_event()
|
||||
void EventLoopManagerQt::did_post_event()
|
||||
{
|
||||
m_process_core_events_timer.start();
|
||||
}
|
||||
|
||||
EventLoopManagerQt::EventLoopManagerQt()
|
||||
{
|
||||
m_process_core_events_timer.setSingleShot(true);
|
||||
m_process_core_events_timer.setInterval(0);
|
||||
QObject::connect(&m_process_core_events_timer, &QTimer::timeout, [] {
|
||||
Core::ThreadEventQueue::current().process();
|
||||
});
|
||||
}
|
||||
|
||||
EventLoopManagerQt::~EventLoopManagerQt() = default;
|
||||
|
||||
void EventLoopManagerQt::wake()
|
||||
{
|
||||
}
|
||||
|
||||
NonnullOwnPtr<Core::EventLoopImplementation> EventLoopManagerQt::make_implementation()
|
||||
{
|
||||
return adopt_own(*new EventLoopImplementationQt);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,16 +16,11 @@
|
|||
|
||||
namespace Ladybird {
|
||||
|
||||
class EventLoopImplementationQt final : public Core::EventLoopImplementation {
|
||||
class EventLoopManagerQt final : public Core::EventLoopManager {
|
||||
public:
|
||||
static NonnullOwnPtr<EventLoopImplementationQt> create() { return adopt_own(*new EventLoopImplementationQt); }
|
||||
|
||||
virtual ~EventLoopImplementationQt() override;
|
||||
|
||||
virtual int exec() override;
|
||||
virtual size_t pump(PumpMode) override;
|
||||
virtual void quit(int) override;
|
||||
virtual void wake() override;
|
||||
EventLoopManagerQt();
|
||||
virtual ~EventLoopManagerQt() override;
|
||||
virtual NonnullOwnPtr<Core::EventLoopImplementation> make_implementation() override;
|
||||
|
||||
virtual void deferred_invoke(Function<void()>) override;
|
||||
|
||||
|
@ -37,21 +32,41 @@ public:
|
|||
|
||||
virtual void did_post_event() override;
|
||||
|
||||
virtual void wake() override;
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
class EventLoopImplementationQt final : public Core::EventLoopImplementation {
|
||||
public:
|
||||
static NonnullOwnPtr<EventLoopImplementationQt> create() { return adopt_own(*new EventLoopImplementationQt); }
|
||||
|
||||
virtual ~EventLoopImplementationQt() override;
|
||||
|
||||
virtual int exec() override;
|
||||
virtual size_t pump(PumpMode) override;
|
||||
virtual void quit(int) override;
|
||||
virtual void wake() override;
|
||||
|
||||
// FIXME: These APIs only exist for obscure use-cases inside SerenityOS. Try to get rid of them.
|
||||
virtual void unquit() override { }
|
||||
virtual bool was_exit_requested() const override { return false; }
|
||||
virtual void notify_forked_and_in_child() override { }
|
||||
virtual int register_signal(int, Function<void(int)>) override { return 0; }
|
||||
virtual void unregister_signal(int) override { }
|
||||
|
||||
void set_main_loop() { m_main_loop = true; }
|
||||
|
||||
private:
|
||||
friend class EventLoopManagerQt;
|
||||
|
||||
EventLoopImplementationQt();
|
||||
bool is_main_loop() const { return m_main_loop; }
|
||||
|
||||
QEventLoop m_event_loop;
|
||||
QTimer m_process_core_events_timer;
|
||||
bool m_main_loop { false };
|
||||
};
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
{
|
||||
QGuiApplication app(arguments.argc, arguments.argv);
|
||||
|
||||
Core::EventLoop::make_implementation = Ladybird::EventLoopImplementationQt::create;
|
||||
Core::EventLoopManager::install(*new Ladybird::EventLoopManagerQt);
|
||||
Core::EventLoop event_loop;
|
||||
|
||||
platform_init();
|
||||
|
|
|
@ -54,7 +54,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
{
|
||||
QApplication app(arguments.argc, arguments.argv);
|
||||
|
||||
Core::EventLoop::make_implementation = Ladybird::EventLoopImplementationQt::create;
|
||||
Core::EventLoopManager::install(*new Ladybird::EventLoopManagerQt);
|
||||
Core::EventLoop event_loop;
|
||||
static_cast<Ladybird::EventLoopImplementationQt&>(event_loop.impl()).set_main_loop();
|
||||
|
||||
|
|
|
@ -24,16 +24,10 @@ Vector<EventLoop&>& event_loop_stack()
|
|||
s_event_loop_stack = new Vector<EventLoop&>;
|
||||
return *s_event_loop_stack;
|
||||
}
|
||||
bool has_event_loop()
|
||||
{
|
||||
return !event_loop_stack().is_empty();
|
||||
}
|
||||
}
|
||||
|
||||
Function<NonnullOwnPtr<EventLoopImplementation>()> EventLoop::make_implementation = EventLoopImplementationUnix::create;
|
||||
|
||||
EventLoop::EventLoop()
|
||||
: m_impl(make_implementation())
|
||||
: m_impl(EventLoopManager::the().make_implementation())
|
||||
{
|
||||
if (event_loop_stack().is_empty()) {
|
||||
event_loop_stack().append(*this);
|
||||
|
@ -94,7 +88,7 @@ size_t EventLoop::pump(WaitMode mode)
|
|||
|
||||
void EventLoop::post_event(Object& receiver, NonnullOwnPtr<Event>&& event)
|
||||
{
|
||||
m_impl->post_event(receiver, move(event));
|
||||
EventLoopManager::the().post_event(receiver, move(event));
|
||||
}
|
||||
|
||||
void EventLoop::add_job(NonnullRefPtr<Promise<NonnullRefPtr<Object>>> job_promise)
|
||||
|
@ -104,16 +98,12 @@ void EventLoop::add_job(NonnullRefPtr<Promise<NonnullRefPtr<Object>>> job_promis
|
|||
|
||||
int EventLoop::register_signal(int signal_number, Function<void(int)> handler)
|
||||
{
|
||||
if (!has_event_loop())
|
||||
return 0;
|
||||
return current().m_impl->register_signal(signal_number, move(handler));
|
||||
return EventLoopManager::the().register_signal(signal_number, move(handler));
|
||||
}
|
||||
|
||||
void EventLoop::unregister_signal(int handler_id)
|
||||
{
|
||||
if (!has_event_loop())
|
||||
return;
|
||||
current().m_impl->unregister_signal(handler_id);
|
||||
EventLoopManager::the().unregister_signal(handler_id);
|
||||
}
|
||||
|
||||
void EventLoop::notify_forked(ForkEvent)
|
||||
|
@ -123,30 +113,22 @@ void EventLoop::notify_forked(ForkEvent)
|
|||
|
||||
int EventLoop::register_timer(Object& object, int milliseconds, bool should_reload, TimerShouldFireWhenNotVisible fire_when_not_visible)
|
||||
{
|
||||
if (!has_event_loop())
|
||||
return 0;
|
||||
return current().m_impl->register_timer(object, milliseconds, should_reload, fire_when_not_visible);
|
||||
return EventLoopManager::the().register_timer(object, milliseconds, should_reload, fire_when_not_visible);
|
||||
}
|
||||
|
||||
bool EventLoop::unregister_timer(int timer_id)
|
||||
{
|
||||
if (!has_event_loop())
|
||||
return false;
|
||||
return current().m_impl->unregister_timer(timer_id);
|
||||
return EventLoopManager::the().unregister_timer(timer_id);
|
||||
}
|
||||
|
||||
void EventLoop::register_notifier(Badge<Notifier>, Notifier& notifier)
|
||||
{
|
||||
if (!has_event_loop())
|
||||
return;
|
||||
current().m_impl->register_notifier(notifier);
|
||||
EventLoopManager::the().register_notifier(notifier);
|
||||
}
|
||||
|
||||
void EventLoop::unregister_notifier(Badge<Notifier>, Notifier& notifier)
|
||||
{
|
||||
if (!has_event_loop())
|
||||
return;
|
||||
current().m_impl->unregister_notifier(notifier);
|
||||
EventLoopManager::the().unregister_notifier(notifier);
|
||||
}
|
||||
|
||||
void EventLoop::wake()
|
||||
|
@ -170,9 +152,4 @@ bool EventLoop::was_exit_requested() const
|
|||
return m_impl->was_exit_requested();
|
||||
}
|
||||
|
||||
void EventLoop::did_post_event(Badge<Core::ThreadEventQueue>)
|
||||
{
|
||||
m_impl->did_post_event();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -94,8 +94,6 @@ public:
|
|||
|
||||
static EventLoop& current();
|
||||
|
||||
static Function<NonnullOwnPtr<EventLoopImplementation>()> make_implementation;
|
||||
|
||||
void did_post_event(Badge<ThreadEventQueue>);
|
||||
EventLoopImplementation& impl() { return *m_impl; }
|
||||
|
||||
|
|
|
@ -7,18 +7,36 @@
|
|||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <LibCore/Event.h>
|
||||
#include <LibCore/EventLoopImplementation.h>
|
||||
#include <LibCore/EventLoopImplementationUnix.h>
|
||||
#include <LibCore/ThreadEventQueue.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
EventLoopImplementation::EventLoopImplementation()
|
||||
EventLoopImplementation::EventLoopImplementation() = default;
|
||||
|
||||
EventLoopImplementation::~EventLoopImplementation() = default;
|
||||
|
||||
static EventLoopManager* s_event_loop_manager;
|
||||
EventLoopManager& EventLoopManager::the()
|
||||
{
|
||||
if (!s_event_loop_manager)
|
||||
s_event_loop_manager = new EventLoopManagerUnix;
|
||||
return *s_event_loop_manager;
|
||||
}
|
||||
|
||||
void EventLoopManager::install(Core::EventLoopManager& manager)
|
||||
{
|
||||
s_event_loop_manager = &manager;
|
||||
}
|
||||
|
||||
EventLoopManager::EventLoopManager()
|
||||
: m_thread_event_queue(ThreadEventQueue::current())
|
||||
{
|
||||
}
|
||||
|
||||
EventLoopImplementation::~EventLoopImplementation() = default;
|
||||
EventLoopManager::~EventLoopManager() = default;
|
||||
|
||||
void EventLoopImplementation::post_event(Object& receiver, NonnullOwnPtr<Event>&& event)
|
||||
void EventLoopManager::post_event(Object& receiver, NonnullOwnPtr<Event>&& event)
|
||||
{
|
||||
m_thread_event_queue.post_event(receiver, move(event));
|
||||
|
||||
|
|
|
@ -11,8 +11,40 @@
|
|||
|
||||
namespace Core {
|
||||
|
||||
class EventLoopImplementation;
|
||||
class ThreadEventQueue;
|
||||
|
||||
class EventLoopManager {
|
||||
public:
|
||||
static EventLoopManager& the();
|
||||
static void install(EventLoopManager&);
|
||||
|
||||
virtual ~EventLoopManager();
|
||||
|
||||
virtual NonnullOwnPtr<EventLoopImplementation> make_implementation() = 0;
|
||||
|
||||
virtual int register_timer(Object&, int milliseconds, bool should_reload, TimerShouldFireWhenNotVisible) = 0;
|
||||
virtual bool unregister_timer(int timer_id) = 0;
|
||||
|
||||
virtual void register_notifier(Notifier&) = 0;
|
||||
virtual void unregister_notifier(Notifier&) = 0;
|
||||
|
||||
void post_event(Object& receiver, NonnullOwnPtr<Event>&&);
|
||||
virtual void did_post_event() = 0;
|
||||
|
||||
virtual void deferred_invoke(Function<void()>) = 0;
|
||||
|
||||
// FIXME: These APIs only exist for obscure use-cases inside SerenityOS. Try to get rid of them.
|
||||
virtual int register_signal(int signal_number, Function<void(int)> handler) = 0;
|
||||
virtual void unregister_signal(int handler_id) = 0;
|
||||
|
||||
virtual void wake() = 0;
|
||||
|
||||
protected:
|
||||
EventLoopManager();
|
||||
ThreadEventQueue& m_thread_event_queue;
|
||||
};
|
||||
|
||||
class EventLoopImplementation {
|
||||
public:
|
||||
virtual ~EventLoopImplementation();
|
||||
|
@ -22,34 +54,18 @@ public:
|
|||
DontWaitForEvents,
|
||||
};
|
||||
|
||||
void post_event(Object& receiver, NonnullOwnPtr<Event>&&);
|
||||
|
||||
virtual int exec() = 0;
|
||||
virtual size_t pump(PumpMode) = 0;
|
||||
virtual void quit(int) = 0;
|
||||
virtual void wake() = 0;
|
||||
|
||||
virtual void deferred_invoke(Function<void()>) = 0;
|
||||
|
||||
virtual int register_timer(Object&, int milliseconds, bool should_reload, TimerShouldFireWhenNotVisible) = 0;
|
||||
virtual bool unregister_timer(int timer_id) = 0;
|
||||
|
||||
virtual void register_notifier(Notifier&) = 0;
|
||||
virtual void unregister_notifier(Notifier&) = 0;
|
||||
|
||||
virtual void did_post_event() = 0;
|
||||
|
||||
// FIXME: These APIs only exist for obscure use-cases inside SerenityOS. Try to get rid of them.
|
||||
virtual void unquit() = 0;
|
||||
virtual bool was_exit_requested() const = 0;
|
||||
virtual void notify_forked_and_in_child() = 0;
|
||||
virtual int register_signal(int signal_number, Function<void(int)> handler) = 0;
|
||||
virtual void unregister_signal(int handler_id) = 0;
|
||||
|
||||
protected:
|
||||
EventLoopImplementation();
|
||||
|
||||
ThreadEventQueue& m_thread_event_queue;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -105,11 +105,8 @@ int EventLoopImplementationUnix::exec()
|
|||
|
||||
size_t EventLoopImplementationUnix::pump(PumpMode mode)
|
||||
{
|
||||
// We can only pump the event loop of the current thread.
|
||||
VERIFY(&m_thread_event_queue == &ThreadEventQueue::current());
|
||||
|
||||
wait_for_events(mode);
|
||||
return m_thread_event_queue.process();
|
||||
static_cast<EventLoopManagerUnix&>(EventLoopManager::the()).wait_for_events(mode);
|
||||
return ThreadEventQueue::current().process();
|
||||
}
|
||||
|
||||
void EventLoopImplementationUnix::quit(int code)
|
||||
|
@ -135,14 +132,20 @@ void EventLoopImplementationUnix::wake()
|
|||
MUST(Core::System::write((*m_wake_pipe_fds)[1], { &wake_event, sizeof(wake_event) }));
|
||||
}
|
||||
|
||||
void EventLoopImplementationUnix::deferred_invoke(Function<void()> invokee)
|
||||
void EventLoopManagerUnix::wake()
|
||||
{
|
||||
int wake_event = 0;
|
||||
MUST(Core::System::write(ThreadData::the().wake_pipe_fds[1], { &wake_event, sizeof(wake_event) }));
|
||||
}
|
||||
|
||||
void EventLoopManagerUnix::deferred_invoke(Function<void()> invokee)
|
||||
{
|
||||
// FIXME: Get rid of the useless DeferredInvocationContext object.
|
||||
auto context = DeferredInvocationContext::construct();
|
||||
post_event(context, make<DeferredInvocationEvent>(context, move(invokee)));
|
||||
}
|
||||
|
||||
void EventLoopImplementationUnix::wait_for_events(PumpMode mode)
|
||||
void EventLoopManagerUnix::wait_for_events(EventLoopImplementation::PumpMode mode)
|
||||
{
|
||||
auto& thread_data = ThreadData::the();
|
||||
|
||||
|
@ -177,7 +180,7 @@ retry:
|
|||
Time now;
|
||||
struct timeval timeout = { 0, 0 };
|
||||
bool should_wait_forever = false;
|
||||
if (mode == PumpMode::WaitForEvents && !has_pending_events) {
|
||||
if (mode == EventLoopImplementation::PumpMode::WaitForEvents && !has_pending_events) {
|
||||
auto next_timer_expiration = get_next_timer_expiration();
|
||||
if (next_timer_expiration.has_value()) {
|
||||
now = Time::now_monotonic_coarse();
|
||||
|
@ -196,11 +199,8 @@ try_select_again:
|
|||
// Because POSIX, we might spuriously return from select() with EINTR; just select again.
|
||||
if (marked_fd_count < 0) {
|
||||
int saved_errno = errno;
|
||||
if (saved_errno == EINTR) {
|
||||
if (m_exit_requested)
|
||||
return;
|
||||
if (saved_errno == EINTR)
|
||||
goto try_select_again;
|
||||
}
|
||||
dbgln("EventLoopImplementationUnix::wait_for_events: {} ({}: {})", marked_fd_count, saved_errno, strerror(saved_errno));
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ inline SignalHandlersInfo* signals_info()
|
|||
return s_signals.ptr();
|
||||
}
|
||||
|
||||
void EventLoopImplementationUnix::dispatch_signal(int signal_number)
|
||||
void EventLoopManagerUnix::dispatch_signal(int signal_number)
|
||||
{
|
||||
auto& info = *signals_info();
|
||||
auto handlers = info.signal_handlers.find(signal_number);
|
||||
|
@ -355,7 +355,7 @@ void EventLoopImplementationUnix::notify_forked_and_in_child()
|
|||
thread_data.pid = getpid();
|
||||
}
|
||||
|
||||
Optional<Time> EventLoopImplementationUnix::get_next_timer_expiration()
|
||||
Optional<Time> EventLoopManagerUnix::get_next_timer_expiration()
|
||||
{
|
||||
auto now = Time::now_monotonic_coarse();
|
||||
Optional<Time> soonest {};
|
||||
|
@ -438,7 +438,7 @@ bool SignalHandlers::remove(int handler_id)
|
|||
return m_handlers.remove(handler_id);
|
||||
}
|
||||
|
||||
void EventLoopImplementationUnix::handle_signal(int signal_number)
|
||||
void EventLoopManagerUnix::handle_signal(int signal_number)
|
||||
{
|
||||
VERIFY(signal_number != 0);
|
||||
auto& thread_data = ThreadData::the();
|
||||
|
@ -457,13 +457,13 @@ void EventLoopImplementationUnix::handle_signal(int signal_number)
|
|||
}
|
||||
}
|
||||
|
||||
int EventLoopImplementationUnix::register_signal(int signal_number, Function<void(int)> handler)
|
||||
int EventLoopManagerUnix::register_signal(int signal_number, Function<void(int)> handler)
|
||||
{
|
||||
VERIFY(signal_number != 0);
|
||||
auto& info = *signals_info();
|
||||
auto handlers = info.signal_handlers.find(signal_number);
|
||||
if (handlers == info.signal_handlers.end()) {
|
||||
auto signal_handlers = adopt_ref(*new SignalHandlers(signal_number, EventLoopImplementationUnix::handle_signal));
|
||||
auto signal_handlers = adopt_ref(*new SignalHandlers(signal_number, EventLoopManagerUnix::handle_signal));
|
||||
auto handler_id = signal_handlers->add(move(handler));
|
||||
info.signal_handlers.set(signal_number, move(signal_handlers));
|
||||
return handler_id;
|
||||
|
@ -472,7 +472,7 @@ int EventLoopImplementationUnix::register_signal(int signal_number, Function<voi
|
|||
}
|
||||
}
|
||||
|
||||
void EventLoopImplementationUnix::unregister_signal(int handler_id)
|
||||
void EventLoopManagerUnix::unregister_signal(int handler_id)
|
||||
{
|
||||
VERIFY(handler_id != 0);
|
||||
int remove_signal_number = 0;
|
||||
|
@ -489,7 +489,7 @@ void EventLoopImplementationUnix::unregister_signal(int handler_id)
|
|||
info.signal_handlers.remove(remove_signal_number);
|
||||
}
|
||||
|
||||
int EventLoopImplementationUnix::register_timer(Object& object, int milliseconds, bool should_reload, TimerShouldFireWhenNotVisible fire_when_not_visible)
|
||||
int EventLoopManagerUnix::register_timer(Object& object, int milliseconds, bool should_reload, TimerShouldFireWhenNotVisible fire_when_not_visible)
|
||||
{
|
||||
VERIFY(milliseconds >= 0);
|
||||
auto& thread_data = ThreadData::the();
|
||||
|
@ -505,25 +505,32 @@ int EventLoopImplementationUnix::register_timer(Object& object, int milliseconds
|
|||
return timer_id;
|
||||
}
|
||||
|
||||
bool EventLoopImplementationUnix::unregister_timer(int timer_id)
|
||||
bool EventLoopManagerUnix::unregister_timer(int timer_id)
|
||||
{
|
||||
auto& thread_data = ThreadData::the();
|
||||
thread_data.id_allocator.deallocate(timer_id);
|
||||
return thread_data.timers.remove(timer_id);
|
||||
}
|
||||
|
||||
void EventLoopImplementationUnix::register_notifier(Notifier& notifier)
|
||||
void EventLoopManagerUnix::register_notifier(Notifier& notifier)
|
||||
{
|
||||
ThreadData::the().notifiers.set(¬ifier);
|
||||
}
|
||||
|
||||
void EventLoopImplementationUnix::unregister_notifier(Notifier& notifier)
|
||||
void EventLoopManagerUnix::unregister_notifier(Notifier& notifier)
|
||||
{
|
||||
ThreadData::the().notifiers.remove(¬ifier);
|
||||
}
|
||||
|
||||
void EventLoopImplementationUnix::did_post_event()
|
||||
void EventLoopManagerUnix::did_post_event()
|
||||
{
|
||||
}
|
||||
|
||||
EventLoopManagerUnix::~EventLoopManagerUnix() = default;
|
||||
|
||||
NonnullOwnPtr<EventLoopImplementation> EventLoopManagerUnix::make_implementation()
|
||||
{
|
||||
return adopt_own(*new EventLoopImplementationUnix);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,35 @@
|
|||
|
||||
namespace Core {
|
||||
|
||||
class EventLoopManagerUnix final : public EventLoopManager {
|
||||
public:
|
||||
virtual ~EventLoopManagerUnix() override;
|
||||
|
||||
virtual NonnullOwnPtr<EventLoopImplementation> make_implementation() override;
|
||||
|
||||
virtual void deferred_invoke(Function<void()>) override;
|
||||
|
||||
virtual int register_timer(Object&, int milliseconds, bool should_reload, TimerShouldFireWhenNotVisible) override;
|
||||
virtual bool unregister_timer(int timer_id) override;
|
||||
|
||||
virtual void register_notifier(Notifier&) override;
|
||||
virtual void unregister_notifier(Notifier&) override;
|
||||
|
||||
virtual void did_post_event() override;
|
||||
|
||||
virtual int register_signal(int signal_number, Function<void(int)> handler) override;
|
||||
virtual void unregister_signal(int handler_id) override;
|
||||
|
||||
virtual void wake() override;
|
||||
|
||||
void wait_for_events(EventLoopImplementation::PumpMode);
|
||||
static Optional<Time> get_next_timer_expiration();
|
||||
|
||||
private:
|
||||
void dispatch_signal(int signal_number);
|
||||
static void handle_signal(int signal_number);
|
||||
};
|
||||
|
||||
class EventLoopImplementationUnix final : public EventLoopImplementation {
|
||||
public:
|
||||
static NonnullOwnPtr<EventLoopImplementationUnix> create() { return make<EventLoopImplementationUnix>(); }
|
||||
|
@ -23,28 +52,11 @@ public:
|
|||
|
||||
virtual void wake() override;
|
||||
|
||||
virtual void deferred_invoke(Function<void()>) override;
|
||||
|
||||
virtual int register_timer(Object&, int milliseconds, bool should_reload, TimerShouldFireWhenNotVisible) override;
|
||||
virtual bool unregister_timer(int timer_id) override;
|
||||
|
||||
virtual void register_notifier(Notifier&) override;
|
||||
virtual void unregister_notifier(Notifier&) override;
|
||||
|
||||
virtual void did_post_event() override;
|
||||
|
||||
virtual void unquit() override;
|
||||
virtual bool was_exit_requested() const override;
|
||||
virtual void notify_forked_and_in_child() override;
|
||||
virtual int register_signal(int signal_number, Function<void(int)> handler) override;
|
||||
virtual void unregister_signal(int handler_id) override;
|
||||
|
||||
private:
|
||||
void wait_for_events(PumpMode);
|
||||
void dispatch_signal(int signal_number);
|
||||
static void handle_signal(int signal_number);
|
||||
static Optional<Time> get_next_timer_expiration();
|
||||
|
||||
bool m_exit_requested { false };
|
||||
int m_exit_code { 0 };
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCore/DeferredInvocationContext.h>
|
||||
#include <LibCore/EventLoopImplementation.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <LibCore/Promise.h>
|
||||
#include <LibCore/ThreadEventQueue.h>
|
||||
|
@ -66,7 +67,7 @@ void ThreadEventQueue::post_event(Core::Object& receiver, NonnullOwnPtr<Core::Ev
|
|||
Threading::MutexLocker lock(m_private->mutex);
|
||||
m_private->queued_events.empend(receiver, move(event));
|
||||
}
|
||||
Core::EventLoop::current().did_post_event({});
|
||||
Core::EventLoopManager::the().did_post_event();
|
||||
}
|
||||
|
||||
void ThreadEventQueue::add_job(NonnullRefPtr<Promise<NonnullRefPtr<Object>>> promise)
|
||||
|
|
Loading…
Reference in a new issue