LibGUI: Rewrite using epoll

select is slow :^)
This commit is contained in:
Bananymous 2026-01-12 23:53:11 +02:00
parent 311a68160c
commit c30fc9d60f
2 changed files with 23 additions and 14 deletions

View File

@ -5,8 +5,8 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/banan-os.h> #include <sys/banan-os.h>
#include <sys/epoll.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/select.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
@ -67,6 +67,18 @@ namespace LibGUI
return BAN::Error::from_errno(errno); return BAN::Error::from_errno(errno);
BAN::ScopeGuard server_closer([server_fd] { close(server_fd); }); BAN::ScopeGuard server_closer([server_fd] { close(server_fd); });
int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd == -1)
return BAN::Error::from_errno(errno);
BAN::ScopeGuard epoll_closer([epoll_fd] { close(epoll_fd); });
epoll_event epoll_event {
.events = EPOLLIN,
.data = { .fd = server_fd },
};
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &epoll_event) == -1)
return BAN::Error::from_errno(errno);
if (fcntl(server_fd, F_SETFD, fcntl(server_fd, F_GETFD) | FD_CLOEXEC) == -1) if (fcntl(server_fd, F_SETFD, fcntl(server_fd, F_GETFD) | FD_CLOEXEC) == -1)
return BAN::Error::from_errno(errno); return BAN::Error::from_errno(errno);
@ -100,7 +112,7 @@ namespace LibGUI
TRY(create_packet.title.append(title)); TRY(create_packet.title.append(title));
TRY(create_packet.send_serialized(server_fd)); TRY(create_packet.send_serialized(server_fd));
auto window = TRY(BAN::UniqPtr<Window>::create(server_fd, attributes)); auto window = TRY(BAN::UniqPtr<Window>::create(server_fd, epoll_fd, attributes));
bool resized = false; bool resized = false;
window->set_resize_window_event_callback([&]() { resized = true; }); window->set_resize_window_event_callback([&]() { resized = true; });
@ -109,6 +121,7 @@ namespace LibGUI
window->set_resize_window_event_callback({}); window->set_resize_window_event_callback({});
server_closer.disable(); server_closer.disable();
epoll_closer.disable();
return window; return window;
} }
@ -261,6 +274,7 @@ namespace LibGUI
{ {
munmap(m_framebuffer_smo, m_width * m_height * 4); munmap(m_framebuffer_smo, m_width * m_height * 4);
close(m_server_fd); close(m_server_fd);
close(m_epoll_fd);
} }
BAN::ErrorOr<void> Window::handle_resize_event(const EventPacket::ResizeWindowEvent& event) BAN::ErrorOr<void> Window::handle_resize_event(const EventPacket::ResizeWindowEvent& event)
@ -289,10 +303,8 @@ namespace LibGUI
void Window::wait_events() void Window::wait_events()
{ {
fd_set fds; epoll_event dummy;
FD_ZERO(&fds); epoll_wait(m_epoll_fd, &dummy, 1, -1);
FD_SET(m_server_fd, &fds);
select(m_server_fd + 1, &fds, nullptr, nullptr, nullptr);
} }
void Window::poll_events() void Window::poll_events()
@ -300,13 +312,8 @@ namespace LibGUI
#define TRY_OR_BREAK(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) break; e.release_value(); }) #define TRY_OR_BREAK(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) break; e.release_value(); })
for (;;) for (;;)
{ {
fd_set fds; epoll_event event;
FD_ZERO(&fds); if (epoll_wait(m_epoll_fd, &event, 1, 0) == 0)
FD_SET(m_server_fd, &fds);
timeval timeout { .tv_sec = 0, .tv_usec = 0 };
select(m_server_fd + 1, &fds, nullptr, nullptr, &timeout);
if (!FD_ISSET(m_server_fd, &fds))
break; break;
auto packet_or_error = recv_packet(m_server_fd); auto packet_or_error = recv_packet(m_server_fd);

View File

@ -81,8 +81,9 @@ namespace LibGUI
int server_fd() const { return m_server_fd; } int server_fd() const { return m_server_fd; }
private: private:
Window(int server_fd, Attributes attributes) Window(int server_fd, int epoll_fd, Attributes attributes)
: m_server_fd(server_fd) : m_server_fd(server_fd)
, m_epoll_fd(epoll_fd)
, m_attributes(attributes) , m_attributes(attributes)
{ } { }
@ -93,6 +94,7 @@ namespace LibGUI
private: private:
const int m_server_fd; const int m_server_fd;
const int m_epoll_fd;
bool m_handling_socket_error { false }; bool m_handling_socket_error { false };