Day52 - fasync, SIGIO, and eventfd Integration¶
Goal¶
Learn how to:
- implement
.fasyncin a char driver - send SIGIO from kernel driver
- receive asynchronous notification in userspace
- bridge SIGIO into epoll using eventfd
- build a unified event-driven userspace loop
1. Driver-Side fasync Support¶
Device Context¶
Add async queue:
File Operations¶
Add:
fasync Handler¶
static int mypoll_fasync(int fd,
struct file *file,
int on)
{
struct mypoll_dev *mydev;
mydev = file->private_data;
if (!mydev)
return -ENODEV;
return fasync_helper(fd,
file,
on,
&mydev->async_queue);
}
Release Cleanup¶
2. Send SIGIO from Driver¶
Inside event generation path:
3. Minimal SIGIO Userspace Test¶
Userspace Flow¶
SIGIO Handler¶
4. Nonblocking Event Read¶
Userspace enables:
and drains events until:
5. eventfd Integration¶
Create eventfd¶
Signal Handler¶
Signal handler only performs:
Example:
static void sigio_handler(int signo)
{
uint64_t value = 1;
(void)signo;
write(g_event_fd, &value, sizeof(value));
}
6. epoll + eventfd¶
epoll monitors eventfd:
7. Final Architecture¶
kernel event
↓
mypoll_generate_event()
↓
queue push
↓
wake_up_interruptible()
↓
kill_fasync()
↓
SIGIO
↓
signal handler
↓
write(eventfd)
↓
epoll_wait()
↓
read(eventfd)
↓
read(/dev/mypoll)
8. Build¶
9. Validation Checklist¶
- SIGIO received successfully
- eventfd wakeup works
- epoll_wait wakes correctly
- userspace drains driver queue
- timer events received
- manual trigger events received
- no blocking inside signal handler
10. Files¶
Suggested files: