Luna/libos/src/EventLoop.cpp

73 lines
1.6 KiB
C++
Raw Normal View History

2023-10-06 20:06:34 +00:00
/**
* @file EventLoop.cpp
* @author apio (cloudapio.eu)
* @brief Base class for event-driven applications.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#include <errno.h>
#include <os/EventLoop.h>
#include <os/File.h>
#include <string.h>
static os::EventLoop* s_the = nullptr;
namespace os
{
EventLoop::EventLoop()
{
s_the = this;
}
EventLoop::~EventLoop()
{
s_the = nullptr;
}
EventLoop& EventLoop::the()
{
check(s_the);
return *s_the;
}
Result<void> EventLoop::register_fd_listener(int fd, void (*listener)(int, int))
{
TRY(m_fd_listeners.try_set(fd, listener));
TRY(m_pollfds.try_append({ .fd = fd, .events = POLLIN, .revents = 0 }));
return {};
}
int EventLoop::run()
{
while (!m_should_quit)
{
for (auto& pfd : m_pollfds) { pfd.revents = 0; }
int rc = poll(m_pollfds.data(), m_pollfds.size(), 1000);
if (!rc) continue;
if (rc < 0 && errno != EINTR)
{
os::println("poll: error: %s", strerror(errno));
return 1;
}
for (usize i = 0; i < m_fd_listeners.size(); i++)
{
if (m_pollfds[i].revents)
m_fd_listeners.try_get(m_pollfds[i].fd)
.value()(m_pollfds[i].fd, m_pollfds[i].revents); // Invoke the callback
}
}
return m_quit_status;
}
void EventLoop::quit(int status)
{
m_quit_status = status;
m_should_quit = true;
}
}