2020-01-18 09:38:21 +01:00
|
|
|
/*
|
2024-10-04 13:19:50 +02:00
|
|
|
* Copyright (c) 2018-2023, Andreas Kling <andreas@ladybird.org>
|
2022-01-02 14:52:38 +01:00
|
|
|
* Copyright (c) 2022, kleines Filmröllchen <malu.bertsch@gmail.com>
|
2022-02-26 09:09:45 -07:00
|
|
|
* Copyright (c) 2022, the SerenityOS developers.
|
2020-01-18 09:38:21 +01:00
|
|
|
*
|
2021-04-22 01:24:48 -07:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-01-18 09:38:21 +01:00
|
|
|
*/
|
|
|
|
|
|
2020-02-14 22:29:06 +01:00
|
|
|
#include <AK/Badge.h>
|
2020-02-06 15:04:03 +01:00
|
|
|
#include <LibCore/Event.h>
|
|
|
|
|
#include <LibCore/EventLoop.h>
|
2024-10-31 12:44:19 +05:00
|
|
|
#include <LibCore/EventLoopImplementation.h>
|
2023-08-06 18:09:39 +02:00
|
|
|
#include <LibCore/EventReceiver.h>
|
2022-12-29 13:20:44 +01:00
|
|
|
#include <LibCore/Promise.h>
|
2023-04-23 19:45:12 +02:00
|
|
|
#include <LibCore/ThreadEventQueue.h>
|
2022-01-23 14:47:10 +01:00
|
|
|
|
2020-02-02 12:34:39 +01:00
|
|
|
namespace Core {
|
|
|
|
|
|
2023-04-24 12:25:14 +02:00
|
|
|
namespace {
|
2025-05-13 07:06:33 -04:00
|
|
|
|
2023-07-11 20:48:56 -05:00
|
|
|
OwnPtr<Vector<EventLoop&>>& event_loop_stack_uninitialized()
|
2022-01-02 15:14:25 +01:00
|
|
|
{
|
2023-08-02 23:03:54 -05:00
|
|
|
thread_local OwnPtr<Vector<EventLoop&>> s_event_loop_stack = nullptr;
|
2023-07-11 20:48:56 -05:00
|
|
|
return s_event_loop_stack;
|
|
|
|
|
}
|
|
|
|
|
Vector<EventLoop&>& event_loop_stack()
|
|
|
|
|
{
|
|
|
|
|
auto& the_stack = event_loop_stack_uninitialized();
|
|
|
|
|
if (the_stack == nullptr)
|
|
|
|
|
the_stack = make<Vector<EventLoop&>>();
|
|
|
|
|
return *the_stack;
|
2022-01-02 15:14:25 +01:00
|
|
|
}
|
2025-05-13 07:06:33 -04:00
|
|
|
|
2021-01-08 12:09:39 -07:00
|
|
|
}
|
|
|
|
|
|
2023-04-24 10:31:49 +02:00
|
|
|
EventLoop::EventLoop()
|
2023-04-25 17:38:48 +02:00
|
|
|
: m_impl(EventLoopManager::the().make_implementation())
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2023-04-24 12:25:14 +02:00
|
|
|
if (event_loop_stack().is_empty()) {
|
|
|
|
|
event_loop_stack().append(*this);
|
2022-04-24 01:48:11 +02:00
|
|
|
}
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-02 12:34:39 +01:00
|
|
|
EventLoop::~EventLoop()
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2023-04-24 12:25:14 +02:00
|
|
|
if (!event_loop_stack().is_empty() && &event_loop_stack().last() == this) {
|
|
|
|
|
event_loop_stack().take_last();
|
|
|
|
|
}
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-11 20:48:56 -05:00
|
|
|
bool EventLoop::is_running()
|
|
|
|
|
{
|
|
|
|
|
auto& stack = event_loop_stack_uninitialized();
|
|
|
|
|
return stack != nullptr && !stack->is_empty();
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-02 12:34:39 +01:00
|
|
|
EventLoop& EventLoop::current()
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2023-11-26 00:21:52 -05:00
|
|
|
if (event_loop_stack().is_empty())
|
|
|
|
|
dbgln("No EventLoop is present, unable to return current one!");
|
2023-04-24 12:25:14 +02:00
|
|
|
return event_loop_stack().last();
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-02 12:34:39 +01:00
|
|
|
void EventLoop::quit(int code)
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2023-05-11 21:58:40 +02:00
|
|
|
ThreadEventQueue::current().cancel_all_pending_jobs();
|
2023-04-24 12:25:14 +02:00
|
|
|
m_impl->quit(code);
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
|
|
|
|
|
2025-04-29 15:41:18 -06:00
|
|
|
bool EventLoop::was_exit_requested()
|
|
|
|
|
{
|
|
|
|
|
return m_impl->was_exit_requested();
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-02 12:34:39 +01:00
|
|
|
struct EventLoopPusher {
|
2019-04-10 17:30:34 +02:00
|
|
|
public:
|
2020-02-02 12:34:39 +01:00
|
|
|
EventLoopPusher(EventLoop& event_loop)
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2023-04-24 12:25:14 +02:00
|
|
|
event_loop_stack().append(event_loop);
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
2020-02-02 12:34:39 +01:00
|
|
|
~EventLoopPusher()
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2023-04-24 12:25:14 +02:00
|
|
|
event_loop_stack().take_last();
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-02-02 12:34:39 +01:00
|
|
|
int EventLoop::exec()
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2020-02-02 12:34:39 +01:00
|
|
|
EventLoopPusher pusher(*this);
|
2023-04-24 12:25:14 +02:00
|
|
|
return m_impl->exec();
|
2019-05-18 13:39:21 +02:00
|
|
|
}
|
2019-04-29 15:57:49 +02:00
|
|
|
|
2021-09-25 19:32:14 +02:00
|
|
|
void EventLoop::spin_until(Function<bool()> goal_condition)
|
|
|
|
|
{
|
|
|
|
|
EventLoopPusher pusher(*this);
|
2025-01-04 22:42:22 -05:00
|
|
|
while (!goal_condition())
|
2021-09-25 19:32:14 +02:00
|
|
|
pump();
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-06 00:55:48 +01:00
|
|
|
size_t EventLoop::pump(WaitMode mode)
|
2019-05-18 13:39:21 +02:00
|
|
|
{
|
2023-04-24 12:25:14 +02:00
|
|
|
return m_impl->pump(mode == WaitMode::WaitForEvents ? EventLoopImplementation::PumpMode::WaitForEvents : EventLoopImplementation::PumpMode::DontWaitForEvents);
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-06 18:09:39 +02:00
|
|
|
void EventLoop::add_job(NonnullRefPtr<Promise<NonnullRefPtr<EventReceiver>>> job_promise)
|
2022-12-29 13:20:44 +01:00
|
|
|
{
|
2023-04-23 19:45:12 +02:00
|
|
|
ThreadEventQueue::current().add_job(move(job_promise));
|
2022-12-29 13:20:44 +01:00
|
|
|
}
|
|
|
|
|
|
2023-04-24 12:25:14 +02:00
|
|
|
int EventLoop::register_signal(int signal_number, Function<void(int)> handler)
|
2020-07-06 15:48:02 -06:00
|
|
|
{
|
2023-04-25 17:38:48 +02:00
|
|
|
return EventLoopManager::the().register_signal(signal_number, move(handler));
|
2020-07-06 15:48:02 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EventLoop::unregister_signal(int handler_id)
|
|
|
|
|
{
|
2023-04-25 17:38:48 +02:00
|
|
|
EventLoopManager::the().unregister_signal(handler_id);
|
2020-09-07 22:44:42 +04:30
|
|
|
}
|
|
|
|
|
|
2025-08-11 11:45:39 +02:00
|
|
|
intptr_t EventLoop::register_timer(EventReceiver& object, int milliseconds, bool should_reload)
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2025-08-11 11:45:39 +02:00
|
|
|
return EventLoopManager::the().register_timer(object, milliseconds, should_reload);
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
|
|
|
|
|
2024-02-18 00:11:38 -05:00
|
|
|
void EventLoop::unregister_timer(intptr_t timer_id)
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2024-02-18 00:10:23 -05:00
|
|
|
EventLoopManager::the().unregister_timer(timer_id);
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-02 12:34:39 +01:00
|
|
|
void EventLoop::register_notifier(Badge<Notifier>, Notifier& notifier)
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2023-04-25 17:38:48 +02:00
|
|
|
EventLoopManager::the().register_notifier(notifier);
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-02 12:34:39 +01:00
|
|
|
void EventLoop::unregister_notifier(Badge<Notifier>, Notifier& notifier)
|
2019-04-10 17:30:34 +02:00
|
|
|
{
|
2023-04-25 17:38:48 +02:00
|
|
|
EventLoopManager::the().unregister_notifier(notifier);
|
2019-04-10 17:30:34 +02:00
|
|
|
}
|
2019-07-14 10:20:57 +02:00
|
|
|
|
2020-02-02 12:34:39 +01:00
|
|
|
void EventLoop::wake()
|
2019-07-14 10:20:57 +02:00
|
|
|
{
|
2023-04-24 12:25:14 +02:00
|
|
|
m_impl->wake();
|
2019-07-14 10:20:57 +02:00
|
|
|
}
|
2020-02-02 12:34:39 +01:00
|
|
|
|
2023-04-23 21:19:37 +02:00
|
|
|
void EventLoop::deferred_invoke(Function<void()> invokee)
|
|
|
|
|
{
|
2025-12-03 11:53:04 +01:00
|
|
|
m_impl->deferred_invoke(move(invokee));
|
2023-04-23 21:19:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void deferred_invoke(Function<void()> invokee)
|
|
|
|
|
{
|
|
|
|
|
EventLoop::current().deferred_invoke(move(invokee));
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-02 12:34:39 +01:00
|
|
|
}
|