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:
parent
43305768cb
commit
a4fbdb7437
12 changed files with 974 additions and 37 deletions
|
|
@ -106,6 +106,8 @@ fileclose(struct file *f)
|
|||
|
||||
if(ff.type == FD_MEMFD)
|
||||
shm_detach(ff.memfd_seg); // the last mapper frees the pages
|
||||
else if(ff.type == FD_EVENT)
|
||||
ev_close(ff.ev);
|
||||
else if(ff.type == FD_PIPE)
|
||||
pipeclose(ff.pipe, ff.writable);
|
||||
else if(ff.type == FD_SOCKET)
|
||||
|
|
@ -144,6 +146,14 @@ filestat(struct file *f, struct stat *st)
|
|||
iunlock(f->ip);
|
||||
return 0;
|
||||
}
|
||||
// An eventfd, timerfd, signalfd or epoll set: Linux calls these anonymous
|
||||
// inodes, and fstat succeeds on them with nothing much to say. A program
|
||||
// that fstat()s every descriptor it is handed should not fail on one.
|
||||
if(f->type == FD_EVENT){
|
||||
memset(st, 0, sizeof(*st));
|
||||
st->nlink = 1;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -155,6 +165,9 @@ fileread(struct file *f, char *addr, int n)
|
|||
if(f->readable == 0)
|
||||
return -1;
|
||||
|
||||
if(f->type == FD_EVENT)
|
||||
return ev_read(f, addr, n);
|
||||
|
||||
// A memfd is a file: read() and write() move bytes in and out of the shared
|
||||
// pages, and the descriptor carries its own offset like any other. mmap is
|
||||
// what it is usually for, but a descriptor that refuses read() is a surprise
|
||||
|
|
@ -248,6 +261,9 @@ filewrite(struct file *f, char *addr, int n)
|
|||
if(f->writable == 0)
|
||||
return -1;
|
||||
|
||||
if(f->type == FD_EVENT)
|
||||
return ev_write(f, addr, n);
|
||||
|
||||
if(f->type == FD_MEMFD){
|
||||
r = memfd_rw(f->memfd_seg, 1, (uint64)addr, f->off, n, 1);
|
||||
if(r > 0)
|
||||
|
|
@ -326,6 +342,9 @@ filewrite(struct file *f, char *addr, int n)
|
|||
int
|
||||
file_poll(struct file *f, int events)
|
||||
{
|
||||
if(f->type == FD_EVENT)
|
||||
return ev_poll(f, events);
|
||||
|
||||
if(f->type == FD_PIPE)
|
||||
return pipe_poll(f->pipe, f->readable, f->writable) &
|
||||
(events | POLLERR | POLLHUP);
|
||||
|
|
|
|||
Loading…
Reference in a new issue