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:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user