Files
banan-os/kernel/kernel/FS/EventFD.cpp
Bananymous 1dc26d3c06 Kernel: Cleanup inode stat updating
Inode now handles stat upates itself and calls sync function to make
updates visible on the underlying filesystem
2026-05-19 13:00:05 +03:00

83 lines
1.8 KiB
C++

#include <kernel/FS/EventFD.h>
#include <kernel/Lock/LockGuard.h>
#include <sys/epoll.h>
namespace Kernel
{
BAN::ErrorOr<BAN::RefPtr<Inode>> EventFD::create(uint64_t initval, bool semaphore)
{
auto* eventfd_ptr = new EventFD(initval, semaphore);
if (eventfd_ptr == nullptr)
return BAN::Error::from_errno(ENOMEM);
return BAN::RefPtr<Inode>(BAN::RefPtr<EventFD>::adopt(eventfd_ptr));
}
EventFD::EventFD(uint64_t initval, bool is_semaphore)
: m_is_semaphore(is_semaphore)
, m_value(initval)
{
m_ino = 0;
m_mode = Mode::IFCHR | Mode::IRUSR | Mode::IWUSR;
m_nlink = 0;
m_uid = 0;
m_gid = 0;
m_size = 0;
m_atime = {};
m_mtime = {};
m_ctime = {};
m_blksize = 8;
m_blocks = 0;
m_dev = 0;
m_rdev = 0;
}
BAN::ErrorOr<size_t> EventFD::read_impl(off_t, BAN::ByteSpan buffer)
{
if (buffer.size() < sizeof(uint64_t))
return BAN::Error::from_errno(EINVAL);
LockGuard _(m_mutex);
while (m_value == 0)
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
const uint64_t read_value = m_is_semaphore ? 1 : m_value.load();
m_value -= read_value;
buffer.as<uint64_t>() = read_value;
epoll_notify(EPOLLOUT);
m_thread_blocker.unblock();
return sizeof(uint64_t);
}
BAN::ErrorOr<size_t> EventFD::write_impl(off_t, BAN::ConstByteSpan buffer)
{
if (buffer.size() < sizeof(uint64_t))
return BAN::Error::from_errno(EINVAL);
const uint64_t write_value = buffer.as<const uint64_t>();
if (write_value == UINT64_MAX)
return BAN::Error::from_errno(EINVAL);
LockGuard _(m_mutex);
while (m_value + write_value < m_value)
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
m_value += write_value;
if (m_value > 0)
epoll_notify(EPOLLIN);
m_thread_blocker.unblock();
return sizeof(uint64_t);
}
}