epoll, eventfd, timerfd, signalfd

The set libwayland's event loop is made of, in kernel/sys/sys_event.c:
four kinds of descriptor with no inode, FD_EVENT, that read() drains
and poll() reports on. They were table entries returning ENOSYS that
read as done.

epoll registers (descriptor, file) pairs, so a closed descriptor
leaves the set; level- and edge-triggered, EPOLLONESHOT. Waiting is
poll()'s, a tick at a time. The old eventfd and signalfd numbers (284,
282) were aliased to the new calls and read flags from a garbage
register; they are their own entries now, with epoll_create and
epoll_pwait.

cmd/evtest checks each, then all four in one set. The plans are
brought up to date: everything Wayland was waiting on is built except
setsockopt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-24 10:59:52 +02:00
commit a4fbdb7437
12 changed files with 974 additions and 37 deletions

View file

@ -108,6 +108,13 @@ int exec(char*, char**, char**);
// file.c
struct file* filealloc(void);
int fdalloc(struct file*);
// sys_event.c: eventfd, timerfd, signalfd and epoll, as files
struct evobj;
void ev_close(struct evobj *);
int ev_poll(struct file *, int events);
int ev_read(struct file *, char *addr, int n);
int ev_write(struct file *, char *addr, int n);
void fileclose(struct file*);
struct file* filedup(struct file*);
void fileinit(void);

View file

@ -3,7 +3,10 @@ struct file {
// returns. It is a descriptor with no name and no inode behind it, which is
// the entire reason memfd exists -- two processes share memory by passing
// the descriptor, not by agreeing on a path or a System V key.
enum { FD_NONE, FD_PIPE, FD_INODE, FD_SOCKET, FD_MEMFD } type;
//
// FD_EVENT: an eventfd, timerfd, signalfd or epoll set -- see
// kernel/sys/sys_event.c, which is the only file that looks inside `ev`.
enum { FD_NONE, FD_PIPE, FD_INODE, FD_SOCKET, FD_MEMFD, FD_EVENT } type;
int ref; // reference count
char readable;
char writable;
@ -20,6 +23,7 @@ struct file {
// the reference counting lives and handing out pointers into it would
// invite somebody to keep one.
int memfd_seg;
struct evobj *ev;
uint64 off;
struct file *fnext; // file.c's free list, while ref is 0
};