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:
@@ -1,3 +1,4 @@
|
||||
#include <kernel/Epoll.h>
|
||||
#include <kernel/FS/Inode.h>
|
||||
#include <kernel/Lock/LockGuard.h>
|
||||
#include <kernel/Memory/FileBackedRegion.h>
|
||||
@@ -249,10 +250,39 @@ namespace Kernel
|
||||
return has_error_impl();
|
||||
}
|
||||
|
||||
bool Inode::has_hangup() const
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
return has_hangup_impl();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Inode::ioctl(int request, void* arg)
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
return ioctl_impl(request, arg);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Inode::add_epoll(class Epoll* epoll)
|
||||
{
|
||||
TRY(m_epolls.push_back(epoll));
|
||||
return {};
|
||||
}
|
||||
|
||||
void Inode::del_epoll(class Epoll* epoll)
|
||||
{
|
||||
for (auto it = m_epolls.begin(); it != m_epolls.end(); it++)
|
||||
{
|
||||
if (*it != epoll)
|
||||
continue;
|
||||
m_epolls.remove(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Inode::epoll_notify(uint32_t event)
|
||||
{
|
||||
for (auto* epoll : m_epolls)
|
||||
epoll->notify(this, event);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <kernel/Thread.h>
|
||||
#include <kernel/Timer/Timer.h>
|
||||
|
||||
#include <kernel/Process.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
@@ -36,8 +36,10 @@ namespace Kernel
|
||||
{
|
||||
auto old_writing_count = m_writing_count.fetch_sub(1);
|
||||
ASSERT(old_writing_count > 0);
|
||||
if (old_writing_count == 1)
|
||||
m_thread_blocker.unblock();
|
||||
if (old_writing_count != 1)
|
||||
return;
|
||||
epoll_notify(EPOLLHUP);
|
||||
m_thread_blocker.unblock();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> Pipe::read_impl(off_t, BAN::ByteSpan buffer)
|
||||
@@ -69,6 +71,8 @@ namespace Kernel
|
||||
|
||||
m_atime = SystemTimer::get().real_time();
|
||||
|
||||
epoll_notify(EPOLLOUT);
|
||||
|
||||
m_thread_blocker.unblock();
|
||||
|
||||
return to_copy;
|
||||
@@ -103,6 +107,8 @@ namespace Kernel
|
||||
m_mtime = current_time;
|
||||
m_ctime = current_time;
|
||||
|
||||
epoll_notify(EPOLLIN);
|
||||
|
||||
m_thread_blocker.unblock();
|
||||
|
||||
return to_copy;
|
||||
|
||||
@@ -226,7 +226,6 @@ namespace Kernel
|
||||
}
|
||||
|
||||
/* SOCKET INODE */
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<TmpSocketInode>> TmpSocketInode::create_new(TmpFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
auto info = create_inode_info(Mode::IFSOCK | mode, uid, gid);
|
||||
|
||||
Reference in New Issue
Block a user