libc_core/epoll.rs
1//! This module provides the `libc` types for Epoll (event polling).
2//!
3//! MUSL: <https://github.com/bminor/musl/blob/c47ad25ea3b484e10326f933e927c0bc8cded3da/include/sys/epoll.h>
4
5use num_enum::TryFromPrimitive;
6
7use crate::poll::PollEvent;
8
9/// 表示 epoll 事件的结构体(对应 Linux 的 `struct epoll_event`)
10///
11/// MUSL: <https://github.com/bminor/musl/blob/c47ad25ea3b484e10326f933e927c0bc8cded3da/include/sys/epoll.h#L49>
12/// TODO: 根据 data 的类型,可能需要使用不同的结构体来表示不同的事件, 对应 C 语言的 `union`
13/// NOTE: 在 x86_64 架构会添加 `__attribute__ ((__packed__))`,以确保结构体的内存对齐
14#[repr(C)]
15#[derive(Clone, Debug)]
16pub struct EpollEvent {
17 /// 事件类型(如可读、可写等,使用 EpollEventType 表示)
18 pub events: EpollEventType,
19 /// 用户数据(如 fd 或标识符),epoll 不做解释
20 pub data: u64,
21}
22
23bitflags! {
24 /// Epoll 事件类型(类似 poll 的事件掩码)
25 #[derive(Clone, Debug)]
26 pub struct EpollEventType: u32 {
27 /// 表示对应的文件描述符可读(包括普通数据和优先数据)
28 const EPOLLIN = 0x001;
29 /// 表示对应的文件描述符可写(低水位标记)
30 const EPOLLOUT = 0x004;
31 /// 文件描述符发生错误(error)
32 const EPOLLERR = 0x008;
33 /// 对端挂起或关闭连接(hang up)
34 const EPOLLHUP = 0x010;
35 /// 有高优先级数据可读(如带外数据)
36 const EPOLLPRI = 0x002;
37 /// 普通数据可读(normal read)
38 const EPOLLRDNORM = 0x040;
39 /// 带外数据可读(band read)
40 const EPOLLRDBAND = 0x080;
41 /// 普通数据可写(normal write)
42 const EPOLLWRNORM = 0x100;
43 /// 带外数据可写(band write)
44 const EPOLLWRBAND = 0x200;
45 /// 有系统消息可读(通常未使用)
46 const EPOLLMSG = 0x400;
47 /// 流被对端关闭,半关闭状态(对端调用 shutdown 写)
48 const EPOLLRDHUP = 0x2000;
49 /// 表示该监听是排他的(exclusive),用于防止多线程同时触发
50 const EPOLLEXCLUSIVE = 0x1000_0000;
51 /// 唤醒系统 suspend 状态(需要 CAP_BLOCK_SUSPEND 权限)
52 const EPOLLWAKEUP = 0x2000_0000;
53 /// 事件触发一次后就自动删除(one-shot 模式)
54 const EPOLLONESHOT = 0x4000_0000;
55 /// 边缘触发(Edge-Triggered)模式
56 const EPOLLET = 0x8000_0000;
57 }
58}
59
60impl EpollEventType {
61 /// 将 EpollEventType 转换为 PollEvent
62 pub fn to_poll(&self) -> PollEvent {
63 PollEvent::from_bits_truncate(self.bits() as u16)
64 }
65}
66
67#[repr(u8)]
68#[derive(Debug, Eq, PartialEq, TryFromPrimitive)]
69/// `epoll_ctl` 操作类型,用于管理 epoll 实例中的监听目标(fd)。
70pub enum EpollCtl {
71 /// 添加一个新的监听目标到 epoll 实例中(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, event))
72 ADD = 1,
73 /// 从 epoll 实例中删除一个监听目标(epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL))
74 DEL = 2,
75 /// 修改已添加目标的监听事件(epoll_ctl(epfd, EPOLL_CTL_MOD, fd, event))
76 MOD = 3,
77}