kernel: Support listening sockets in poll()

This commit is contained in:
apio 2023-08-03 16:28:14 +02:00
parent 5b89fccb6a
commit 15192837c0
Signed by: apio
GPG Key ID: B8A7D06E42258954
4 changed files with 35 additions and 5 deletions

View File

@ -65,6 +65,10 @@ class Socket : public VFS::FileInode
m_metadata.nlinks--;
}
virtual bool can_accept_connections() const = 0;
virtual bool can_read_data() const = 0;
virtual ~Socket() = default;
protected:

View File

@ -17,6 +17,16 @@ class UnixSocket : public Socket
return (m_state == Connected || m_state == Reset) && !m_data.size();
}
bool can_read_data() const override
{
return (m_state == Connected || m_state == Reset) && m_data.size();
}
bool can_accept_connections() const override
{
return !m_listen_queue.is_empty();
}
Result<usize> send(const u8*, usize, int) override;
Result<usize> recv(u8*, usize, int) const override;

View File

@ -2,6 +2,7 @@
#include "Pledge.h"
#include "fs/VFS.h"
#include "memory/MemoryManager.h"
#include "net/Socket.h"
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
#include <bits/poll.h>
@ -47,12 +48,27 @@ Result<u64> sys_poll(Registers*, SyscallArgs args)
auto& inode = inodes[i];
if (!inode) continue;
if (kfds[i].events & POLLIN && !inode->will_block_if_read())
if (kfds[i].events & POLLIN)
{
if (inode->type() == VFS::InodeType::Socket)
{
auto socket = (Socket*)inode.ptr();
if (socket->can_read_data() || socket->can_accept_connections())
{
fds_with_events++;
kfds[i].revents |= POLLIN;
}
}
else
{
if (!inode->will_block_if_read())
{
fds_with_events++;
kfds[i].revents |= POLLIN;
}
}
}
}
if (!fds_with_events && (timeout > 0 || infinite))
{

View File

@ -37,7 +37,7 @@ template <typename T, usize Size> class CircularQueue
* @return true The queue is empty.
* @return false The queue is not empty.
*/
bool is_empty()
bool is_empty() const
{
return m_tail.load() == m_head.load();
}
@ -124,7 +124,7 @@ template <typename T> class DynamicCircularQueue
* @return true The queue is empty.
* @return false The queue is not empty.
*/
bool is_empty()
bool is_empty() const
{
return m_tail.load() == m_head.load();
}