Files
banan-os/kernel/include/kernel/Epoll.h
DcraftBg 647d6a273d Kernel: Changed stat values from func to be field
- Removed virtual functions for all of the stat stuff.
This did however introduce some issues, mainly with /proc
becoming out of sync if you changed your ID. I propose we
do the linux thing and just have a stat update function
which is optional, but allows dynamic updates of stat fields
for cases such as those in uid/gid in /proc.
- Simplified the API, although still kind of annoying
it is a bit simpler.
- Moved some of the FS structure from having the FS inode inside
the in memory inode to a Serialise <-> Deserialise model where
Inodes are deserialised from disk into in memory ones and then
back into on disk ones when it comes time for syncing.
This makes it semantically better in my opinion, as it explicitly
separates disk and non-disk functionality.
2026-05-15 20:49:04 +03:00

103 lines
2.2 KiB
C++

#pragma once
#include <BAN/HashMap.h>
#include <kernel/FS/Inode.h>
#include <kernel/Lock/Mutex.h>
#include <sys/epoll.h>
namespace Kernel
{
class Epoll final : public Inode
{
public:
static BAN::ErrorOr<BAN::RefPtr<Epoll>> create();
~Epoll();
BAN::ErrorOr<void> ctl(int op, int fd, BAN::RefPtr<Inode> inode, epoll_event event);
BAN::ErrorOr<size_t> wait(BAN::Span<epoll_event> events, uint64_t waketime_ns);
void notify(BAN::RefPtr<Inode> inode, uint32_t event);
private:
Epoll() {
m_ino = 0;
m_mode = Mode::IRUSR | Mode::IWUSR;
m_nlink = 0;
m_uid = 0;
m_gid = 0;
m_size = 0;
m_atime = {};
m_mtime = {};
m_ctime = {};
m_blksize = PAGE_SIZE;
m_blocks = 0;
m_dev = 0;
m_rdev = 0;
}
public:
bool is_epoll() const override { return true; }
const FileSystem* filesystem() const override { return nullptr; }
bool can_read_impl() const override { return false; }
bool can_write_impl() const override { return false; }
bool has_error_impl() const override { return false; }
bool has_hungup_impl() const override { return false; }
BAN::ErrorOr<void> fsync_impl() override { return {}; }
private:
struct ListenEventList
{
ListenEventList() = default;
ListenEventList(const ListenEventList&) = delete;
ListenEventList& operator=(const ListenEventList&) = delete;
ListenEventList(ListenEventList&& other)
: events(BAN::move(other.events))
{}
ListenEventList& operator=(ListenEventList&& other)
{
events = BAN::move(other.events);
return *this;
}
BAN::HashMap<int, epoll_event> events;
bool has_fd(int fd) const
{
return events.contains(fd);
}
bool empty() const
{
return events.empty();
}
BAN::ErrorOr<void> add_fd(int fd, epoll_event event)
{
TRY(events.insert(fd, event));
return {};
}
void remove_fd(int fd)
{
events.remove(fd);
}
};
private:
Mutex m_mutex;
ThreadBlocker m_thread_blocker;
SpinLock m_ready_lock;
BAN::HashMap<BAN::RefPtr<Inode>, uint32_t> m_ready_events;
BAN::HashMap<BAN::RefPtr<Inode>, uint32_t> m_processing_events;
BAN::HashMap<BAN::RefPtr<Inode>, ListenEventList> m_listening_events;
};
}