86 lines
2.4 KiB
C++
86 lines
2.4 KiB
C++
/**
|
|
* @file EventLoop.h
|
|
* @author apio (cloudapio.eu)
|
|
* @brief Base class for event-driven applications.
|
|
*
|
|
* @copyright Copyright (c) 2023, the Luna authors.
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
#include <luna/HashMap.h>
|
|
#include <luna/Vector.h>
|
|
#include <sys/poll.h>
|
|
|
|
namespace os
|
|
{
|
|
/**
|
|
* @brief Event loop implementation.
|
|
*/
|
|
class EventLoop
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Construct a new event loop, which will automatically register itself as the current global event loop.
|
|
*/
|
|
EventLoop();
|
|
|
|
~EventLoop();
|
|
|
|
EventLoop(EventLoop&&) = delete;
|
|
EventLoop(const EventLoop&) = delete;
|
|
|
|
/**
|
|
* @brief Fetch the current global event loop.
|
|
*
|
|
* @return EventLoop& The current global event loop.
|
|
*/
|
|
static EventLoop& the();
|
|
|
|
/**
|
|
* @brief Register a new event listener on a file descriptor.
|
|
*
|
|
* @param fd The file descriptor to listen on.
|
|
* @param listener The callback function to invoke when events occur on the file descriptor. The first parameter
|
|
* is the file descriptor registered, and the second argument is the type of event (POLLIN or POLLHUP)
|
|
* @return Result<void> Whether the operation succeeded.
|
|
*/
|
|
Result<void> register_fd_listener(int fd, void (*listener)(int, int));
|
|
|
|
/**
|
|
* @brief Register a new POSIX signal handler.
|
|
*
|
|
* Unlike standard POSIX signal handling, this handler will be run synchronously as part of the event loop,
|
|
* eliminating many problems with asynchronous signal handling.
|
|
*/
|
|
Result<void> register_signal_handler(int sig, void (*handler)(int));
|
|
|
|
/**
|
|
* @brief Run the event loop until it is asked to quit.
|
|
*
|
|
* @return int The status passed to the quit() method.
|
|
*/
|
|
int run();
|
|
|
|
/**
|
|
* @brief Ask the event loop to quit.
|
|
*
|
|
* @param status The status value to return from run().
|
|
*/
|
|
void quit(int status = 0);
|
|
|
|
private:
|
|
HashMap<int, void (*)(int, int)> m_fd_listeners;
|
|
HashMap<int, void (*)(int)> m_signal_handlers;
|
|
Vector<struct pollfd> m_pollfds;
|
|
|
|
static void handle_signal(int sig);
|
|
static void handle_quit_signal(int);
|
|
|
|
bool m_should_quit { false };
|
|
int m_quit_status { 0 };
|
|
|
|
int m_signal_pipe[2];
|
|
};
|
|
}
|