Kernel/LibC: Implement basic epoll

This implementation is on top of inodes instead of fds as linux does it.
If I start finding ports/software that relies on epoll allowing
duplicate inodes, I will do what linux does.

I'm probably missing multiple epoll_notify's which may cause hangs but
the system seems to work fine :dd:
This commit is contained in:
2025-05-13 10:10:35 +03:00
parent 143a00626b
commit 1bcd1edbf5
43 changed files with 627 additions and 119 deletions

View File

@@ -6,6 +6,7 @@
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/epoll.h>
namespace Kernel
{
@@ -271,6 +272,11 @@ namespace Kernel
return m_send_window.data_size < m_send_window.buffer->size();
}
bool TCPSocket::has_hangup_impl() const
{
return m_has_connected && m_state != State::Established;
}
BAN::ErrorOr<size_t> TCPSocket::return_with_maybe_zero()
{
ASSERT(m_state != State::Established);
@@ -577,6 +583,8 @@ namespace Kernel
memcpy(buffer + m_recv_window.data_size, payload.data(), payload.size());
m_recv_window.data_size += payload.size();
epoll_notify(EPOLLIN);
dprintln_if(DEBUG_TCP, "Received {} bytes", payload.size());
if (m_next_flags == 0)
@@ -726,6 +734,8 @@ namespace Kernel
m_send_window.current_seq += to_send;
i += to_send;
epoll_notify(EPOLLOUT);
}
m_send_window.last_send_ms = current_ms;

View File

@@ -2,6 +2,8 @@
#include <kernel/Networking/UDPSocket.h>
#include <kernel/Thread.h>
#include <sys/epoll.h>
namespace Kernel
{
@@ -70,6 +72,8 @@ namespace Kernel
m_packets.emplace(packet_info);
m_packet_total_size += payload.size();
epoll_notify(EPOLLIN);
m_packet_thread_blocker.unblock();
}

View File

@@ -5,6 +5,7 @@
#include <kernel/Scheduler.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/un.h>
namespace Kernel
@@ -62,6 +63,7 @@ namespace Kernel
if (auto connection = connection_info.connection.lock(); connection && connection->m_info.has<ConnectionInfo>())
{
connection->m_info.get<ConnectionInfo>().target_closed = true;
connection->epoll_notify(EPOLLHUP);
connection->m_packet_thread_blocker.unblock();
}
}
@@ -172,6 +174,8 @@ namespace Kernel
TRY(Thread::current().block_or_eintr_indefinite(target_info.pending_thread_blocker));
}
target->epoll_notify(EPOLLIN);
while (!connection_info.connection_done)
Processor::yield();
@@ -263,6 +267,8 @@ namespace Kernel
if (!is_streaming())
m_packet_sizes.push(packet.size());
epoll_notify(EPOLLIN);
m_packet_thread_blocker.unblock();
m_packet_lock.unlock(state);
return {};
@@ -295,6 +301,17 @@ namespace Kernel
return true;
}
bool UnixDomainSocket::has_hangup_impl() const
{
if (m_info.has<ConnectionInfo>())
{
auto& connection_info = m_info.get<ConnectionInfo>();
return connection_info.target_closed;
}
return false;
}
BAN::ErrorOr<size_t> UnixDomainSocket::sendto_impl(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len)
{
if (message.size() > s_packet_buffer_size)
@@ -390,6 +407,8 @@ namespace Kernel
m_packet_thread_blocker.unblock();
m_packet_lock.unlock(state);
epoll_notify(EPOLLOUT);
return nread;
}