xref: /DragonOS/kernel/src/net/event_poll/mod.rs (revision 406099704eb939ae23b18f0cfb3ed36c534c1c84)
1*40609970SGnoCiYeH use core::{
2*40609970SGnoCiYeH     fmt::Debug,
3*40609970SGnoCiYeH     sync::atomic::{AtomicBool, Ordering},
4*40609970SGnoCiYeH };
5*40609970SGnoCiYeH 
6*40609970SGnoCiYeH use alloc::{
7*40609970SGnoCiYeH     collections::LinkedList,
8*40609970SGnoCiYeH     sync::{Arc, Weak},
9*40609970SGnoCiYeH     vec::Vec,
10*40609970SGnoCiYeH };
11*40609970SGnoCiYeH 
12*40609970SGnoCiYeH use crate::{
13*40609970SGnoCiYeH     arch::sched::sched,
14*40609970SGnoCiYeH     filesystem::vfs::{
15*40609970SGnoCiYeH         file::{File, FileMode},
16*40609970SGnoCiYeH         FilePrivateData, IndexNode, Metadata,
17*40609970SGnoCiYeH     },
18*40609970SGnoCiYeH     include::bindings::bindings::INT32_MAX,
19*40609970SGnoCiYeH     libs::{
20*40609970SGnoCiYeH         rbtree::RBTree,
21*40609970SGnoCiYeH         rwlock::RwLock,
22*40609970SGnoCiYeH         spinlock::{SpinLock, SpinLockGuard},
23*40609970SGnoCiYeH         wait_queue::WaitQueue,
24*40609970SGnoCiYeH     },
25*40609970SGnoCiYeH     process::ProcessManager,
26*40609970SGnoCiYeH     syscall::SystemError,
27*40609970SGnoCiYeH     time::{
28*40609970SGnoCiYeH         timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
29*40609970SGnoCiYeH         TimeSpec,
30*40609970SGnoCiYeH     },
31*40609970SGnoCiYeH };
32*40609970SGnoCiYeH 
33*40609970SGnoCiYeH pub mod syscall;
34*40609970SGnoCiYeH 
35*40609970SGnoCiYeH #[derive(Debug, Clone)]
36*40609970SGnoCiYeH pub struct LockedEventPoll(Arc<SpinLock<EventPoll>>);
37*40609970SGnoCiYeH 
38*40609970SGnoCiYeH /// 内核的Epoll对象结构体,当用户创建一个Epoll时,内核就会创建一个该类型对象
39*40609970SGnoCiYeH /// 它对应一个epfd
40*40609970SGnoCiYeH #[derive(Debug)]
41*40609970SGnoCiYeH pub struct EventPoll {
42*40609970SGnoCiYeH     /// epoll_wait用到的等待队列
43*40609970SGnoCiYeH     epoll_wq: WaitQueue,
44*40609970SGnoCiYeH     /// 维护所有添加进来的socket的红黑树
45*40609970SGnoCiYeH     ep_items: RBTree<i32, Arc<EPollItem>>,
46*40609970SGnoCiYeH     /// 接收就绪的描述符列表
47*40609970SGnoCiYeH     ready_list: LinkedList<Arc<EPollItem>>,
48*40609970SGnoCiYeH     /// 是否已经关闭
49*40609970SGnoCiYeH     shutdown: AtomicBool,
50*40609970SGnoCiYeH     self_ref: Option<Weak<SpinLock<EventPoll>>>,
51*40609970SGnoCiYeH }
52*40609970SGnoCiYeH 
53*40609970SGnoCiYeH impl EventPoll {
54*40609970SGnoCiYeH     pub const EP_MAX_EVENTS: u32 = INT32_MAX / (core::mem::size_of::<EPollEvent>() as u32);
55*40609970SGnoCiYeH     pub fn new() -> Self {
56*40609970SGnoCiYeH         Self {
57*40609970SGnoCiYeH             epoll_wq: WaitQueue::INIT,
58*40609970SGnoCiYeH             ep_items: RBTree::new(),
59*40609970SGnoCiYeH             ready_list: LinkedList::new(),
60*40609970SGnoCiYeH             shutdown: AtomicBool::new(false),
61*40609970SGnoCiYeH             self_ref: None,
62*40609970SGnoCiYeH         }
63*40609970SGnoCiYeH     }
64*40609970SGnoCiYeH }
65*40609970SGnoCiYeH 
66*40609970SGnoCiYeH /// EpollItem表示的是Epoll所真正管理的对象
67*40609970SGnoCiYeH /// 每当用户向Epoll添加描述符时都会注册一个新的EpollItem,EpollItem携带了一些被监听的描述符的必要信息
68*40609970SGnoCiYeH #[derive(Debug)]
69*40609970SGnoCiYeH pub struct EPollItem {
70*40609970SGnoCiYeH     /// 对应的Epoll
71*40609970SGnoCiYeH     epoll: Weak<SpinLock<EventPoll>>,
72*40609970SGnoCiYeH     /// 用户注册的事件
73*40609970SGnoCiYeH     event: RwLock<EPollEvent>,
74*40609970SGnoCiYeH     /// 监听的描述符
75*40609970SGnoCiYeH     fd: i32,
76*40609970SGnoCiYeH     /// 对应的文件
77*40609970SGnoCiYeH     file: Weak<SpinLock<File>>,
78*40609970SGnoCiYeH }
79*40609970SGnoCiYeH 
80*40609970SGnoCiYeH impl EPollItem {
81*40609970SGnoCiYeH     pub fn new(
82*40609970SGnoCiYeH         epoll: Weak<SpinLock<EventPoll>>,
83*40609970SGnoCiYeH         events: EPollEvent,
84*40609970SGnoCiYeH         fd: i32,
85*40609970SGnoCiYeH         file: Weak<SpinLock<File>>,
86*40609970SGnoCiYeH     ) -> Self {
87*40609970SGnoCiYeH         Self {
88*40609970SGnoCiYeH             epoll,
89*40609970SGnoCiYeH             event: RwLock::new(events),
90*40609970SGnoCiYeH             fd,
91*40609970SGnoCiYeH             file,
92*40609970SGnoCiYeH         }
93*40609970SGnoCiYeH     }
94*40609970SGnoCiYeH 
95*40609970SGnoCiYeH     pub fn epoll(&self) -> Weak<SpinLock<EventPoll>> {
96*40609970SGnoCiYeH         self.epoll.clone()
97*40609970SGnoCiYeH     }
98*40609970SGnoCiYeH 
99*40609970SGnoCiYeH     pub fn event(&self) -> &RwLock<EPollEvent> {
100*40609970SGnoCiYeH         &self.event
101*40609970SGnoCiYeH     }
102*40609970SGnoCiYeH 
103*40609970SGnoCiYeH     pub fn file(&self) -> Weak<SpinLock<File>> {
104*40609970SGnoCiYeH         self.file.clone()
105*40609970SGnoCiYeH     }
106*40609970SGnoCiYeH 
107*40609970SGnoCiYeH     pub fn fd(&self) -> i32 {
108*40609970SGnoCiYeH         self.fd
109*40609970SGnoCiYeH     }
110*40609970SGnoCiYeH 
111*40609970SGnoCiYeH     /// ## 通过epoll_item来执行绑定文件的poll方法,并获取到感兴趣的事件
112*40609970SGnoCiYeH     fn ep_item_poll(&self) -> EPollEventType {
113*40609970SGnoCiYeH         let file = self.file.upgrade();
114*40609970SGnoCiYeH         if file.is_none() {
115*40609970SGnoCiYeH             return EPollEventType::empty();
116*40609970SGnoCiYeH         }
117*40609970SGnoCiYeH         if let Ok(events) = file.unwrap().lock_irqsave().poll() {
118*40609970SGnoCiYeH             let events = events as u32 & self.event.read().events;
119*40609970SGnoCiYeH             return EPollEventType::from_bits_truncate(events);
120*40609970SGnoCiYeH         }
121*40609970SGnoCiYeH         return EPollEventType::empty();
122*40609970SGnoCiYeH     }
123*40609970SGnoCiYeH }
124*40609970SGnoCiYeH 
125*40609970SGnoCiYeH /// ### Epoll文件的私有信息
126*40609970SGnoCiYeH #[derive(Debug, Clone)]
127*40609970SGnoCiYeH pub struct EPollPrivateData {
128*40609970SGnoCiYeH     epoll: LockedEventPoll,
129*40609970SGnoCiYeH }
130*40609970SGnoCiYeH 
131*40609970SGnoCiYeH /// ### 该结构体将Epoll加入文件系统
132*40609970SGnoCiYeH #[derive(Debug)]
133*40609970SGnoCiYeH pub struct EPollInode {
134*40609970SGnoCiYeH     epoll: LockedEventPoll,
135*40609970SGnoCiYeH }
136*40609970SGnoCiYeH 
137*40609970SGnoCiYeH impl EPollInode {
138*40609970SGnoCiYeH     pub fn new(epoll: LockedEventPoll) -> Arc<Self> {
139*40609970SGnoCiYeH         Arc::new(Self { epoll })
140*40609970SGnoCiYeH     }
141*40609970SGnoCiYeH }
142*40609970SGnoCiYeH 
143*40609970SGnoCiYeH impl IndexNode for EPollInode {
144*40609970SGnoCiYeH     fn read_at(
145*40609970SGnoCiYeH         &self,
146*40609970SGnoCiYeH         _offset: usize,
147*40609970SGnoCiYeH         _len: usize,
148*40609970SGnoCiYeH         _buf: &mut [u8],
149*40609970SGnoCiYeH         _data: &mut crate::filesystem::vfs::FilePrivateData,
150*40609970SGnoCiYeH     ) -> Result<usize, crate::syscall::SystemError> {
151*40609970SGnoCiYeH         Err(SystemError::ENOSYS)
152*40609970SGnoCiYeH     }
153*40609970SGnoCiYeH 
154*40609970SGnoCiYeH     fn write_at(
155*40609970SGnoCiYeH         &self,
156*40609970SGnoCiYeH         _offset: usize,
157*40609970SGnoCiYeH         _len: usize,
158*40609970SGnoCiYeH         _buf: &[u8],
159*40609970SGnoCiYeH         _data: &mut crate::filesystem::vfs::FilePrivateData,
160*40609970SGnoCiYeH     ) -> Result<usize, crate::syscall::SystemError> {
161*40609970SGnoCiYeH         Err(SystemError::ENOSYS)
162*40609970SGnoCiYeH     }
163*40609970SGnoCiYeH 
164*40609970SGnoCiYeH     fn poll(&self) -> Result<usize, crate::syscall::SystemError> {
165*40609970SGnoCiYeH         // 需要实现epoll嵌套epoll时,需要实现这里
166*40609970SGnoCiYeH         todo!()
167*40609970SGnoCiYeH     }
168*40609970SGnoCiYeH 
169*40609970SGnoCiYeH     fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> {
170*40609970SGnoCiYeH         todo!()
171*40609970SGnoCiYeH     }
172*40609970SGnoCiYeH 
173*40609970SGnoCiYeH     fn as_any_ref(&self) -> &dyn core::any::Any {
174*40609970SGnoCiYeH         self
175*40609970SGnoCiYeH     }
176*40609970SGnoCiYeH 
177*40609970SGnoCiYeH     fn list(&self) -> Result<Vec<alloc::string::String>, crate::syscall::SystemError> {
178*40609970SGnoCiYeH         Err(SystemError::ENOSYS)
179*40609970SGnoCiYeH     }
180*40609970SGnoCiYeH 
181*40609970SGnoCiYeH     fn metadata(&self) -> Result<Metadata, SystemError> {
182*40609970SGnoCiYeH         Ok(Metadata::default())
183*40609970SGnoCiYeH     }
184*40609970SGnoCiYeH 
185*40609970SGnoCiYeH     fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
186*40609970SGnoCiYeH         // 释放资源
187*40609970SGnoCiYeH         let mut epoll = self.epoll.0.lock_irqsave();
188*40609970SGnoCiYeH 
189*40609970SGnoCiYeH         // 唤醒epoll上面等待的所有进程
190*40609970SGnoCiYeH         epoll.shutdown.store(true, Ordering::SeqCst);
191*40609970SGnoCiYeH         epoll.ep_wake_all();
192*40609970SGnoCiYeH 
193*40609970SGnoCiYeH         let fds = epoll.ep_items.keys().cloned().collect::<Vec<_>>();
194*40609970SGnoCiYeH 
195*40609970SGnoCiYeH         // 清理红黑树里面的epitems
196*40609970SGnoCiYeH         for fd in fds {
197*40609970SGnoCiYeH             let file = ProcessManager::current_pcb()
198*40609970SGnoCiYeH                 .fd_table()
199*40609970SGnoCiYeH                 .read()
200*40609970SGnoCiYeH                 .get_file_by_fd(fd);
201*40609970SGnoCiYeH 
202*40609970SGnoCiYeH             if file.is_some() {
203*40609970SGnoCiYeH                 file.unwrap()
204*40609970SGnoCiYeH                     .lock_irqsave()
205*40609970SGnoCiYeH                     .remove_epoll(&Arc::downgrade(&self.epoll.0))?;
206*40609970SGnoCiYeH             }
207*40609970SGnoCiYeH 
208*40609970SGnoCiYeH             epoll.ep_items.remove(&fd);
209*40609970SGnoCiYeH         }
210*40609970SGnoCiYeH 
211*40609970SGnoCiYeH         Ok(())
212*40609970SGnoCiYeH     }
213*40609970SGnoCiYeH 
214*40609970SGnoCiYeH     fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
215*40609970SGnoCiYeH         Ok(())
216*40609970SGnoCiYeH     }
217*40609970SGnoCiYeH }
218*40609970SGnoCiYeH 
219*40609970SGnoCiYeH impl EventPoll {
220*40609970SGnoCiYeH     /// ## 创建epoll对象
221*40609970SGnoCiYeH     ///
222*40609970SGnoCiYeH     /// ### 参数
223*40609970SGnoCiYeH     /// - flags: 创建的epoll文件的FileMode
224*40609970SGnoCiYeH     ///
225*40609970SGnoCiYeH     /// ### 返回值
226*40609970SGnoCiYeH     /// - 成功则返回Ok(fd),否则返回Err
227*40609970SGnoCiYeH     pub fn do_create_epoll(flags: FileMode) -> Result<usize, SystemError> {
228*40609970SGnoCiYeH         if !flags.difference(FileMode::O_CLOEXEC).is_empty() {
229*40609970SGnoCiYeH             return Err(SystemError::EINVAL);
230*40609970SGnoCiYeH         }
231*40609970SGnoCiYeH 
232*40609970SGnoCiYeH         // 创建epoll
233*40609970SGnoCiYeH         let epoll = LockedEventPoll(Arc::new(SpinLock::new(EventPoll::new())));
234*40609970SGnoCiYeH         epoll.0.lock_irqsave().self_ref = Some(Arc::downgrade(&epoll.0));
235*40609970SGnoCiYeH 
236*40609970SGnoCiYeH         // 创建epoll的inode对象
237*40609970SGnoCiYeH         let epoll_inode = EPollInode::new(epoll.clone());
238*40609970SGnoCiYeH 
239*40609970SGnoCiYeH         let mut ep_file = File::new(
240*40609970SGnoCiYeH             epoll_inode,
241*40609970SGnoCiYeH             FileMode::O_RDWR | (flags & FileMode::O_CLOEXEC),
242*40609970SGnoCiYeH         )?;
243*40609970SGnoCiYeH 
244*40609970SGnoCiYeH         // 设置ep_file的FilePrivateData
245*40609970SGnoCiYeH         ep_file.private_data = FilePrivateData::EPoll(EPollPrivateData { epoll });
246*40609970SGnoCiYeH 
247*40609970SGnoCiYeH         let current_pcb = ProcessManager::current_pcb();
248*40609970SGnoCiYeH         let fd_table = current_pcb.fd_table();
249*40609970SGnoCiYeH         let mut fd_table_guard = fd_table.write();
250*40609970SGnoCiYeH 
251*40609970SGnoCiYeH         let fd = fd_table_guard.alloc_fd(ep_file, None)?;
252*40609970SGnoCiYeH 
253*40609970SGnoCiYeH         Ok(fd as usize)
254*40609970SGnoCiYeH     }
255*40609970SGnoCiYeH 
256*40609970SGnoCiYeH     /// ## epoll_ctl的具体实现
257*40609970SGnoCiYeH     ///
258*40609970SGnoCiYeH     /// 根据不同的op对epoll文件进行增删改
259*40609970SGnoCiYeH     ///
260*40609970SGnoCiYeH     /// ### 参数
261*40609970SGnoCiYeH     /// - epfd: 操作的epoll文件描述符
262*40609970SGnoCiYeH     /// - op: 对应的操作
263*40609970SGnoCiYeH     /// - fd: 操作对应的文件描述符
264*40609970SGnoCiYeH     /// - epds: 从用户态传入的event,若op为EpollCtlAdd,则对应注册的监听事件,若op为EPollCtlMod,则对应更新的事件,删除操作不涉及此字段
265*40609970SGnoCiYeH     /// - nonblock: 定义这次操作是否为非阻塞(有可能其他地方占有EPoll的锁)
266*40609970SGnoCiYeH     pub fn do_epoll_ctl(
267*40609970SGnoCiYeH         epfd: i32,
268*40609970SGnoCiYeH         op: EPollCtlOption,
269*40609970SGnoCiYeH         fd: i32,
270*40609970SGnoCiYeH         epds: &mut EPollEvent,
271*40609970SGnoCiYeH         nonblock: bool,
272*40609970SGnoCiYeH     ) -> Result<usize, SystemError> {
273*40609970SGnoCiYeH         let current_pcb = ProcessManager::current_pcb();
274*40609970SGnoCiYeH         let fd_table = current_pcb.fd_table();
275*40609970SGnoCiYeH         let fd_table_guard = fd_table.read();
276*40609970SGnoCiYeH 
277*40609970SGnoCiYeH         // 获取epoll和对应fd指向的文件
278*40609970SGnoCiYeH         let ep_file = fd_table_guard
279*40609970SGnoCiYeH             .get_file_by_fd(epfd)
280*40609970SGnoCiYeH             .ok_or(SystemError::EBADF)?;
281*40609970SGnoCiYeH         let dst_file = fd_table_guard
282*40609970SGnoCiYeH             .get_file_by_fd(fd)
283*40609970SGnoCiYeH             .ok_or(SystemError::EBADF)?;
284*40609970SGnoCiYeH 
285*40609970SGnoCiYeH         // 检查是否允许 EPOLLWAKEUP
286*40609970SGnoCiYeH         if op != EPollCtlOption::EpollCtlDel {
287*40609970SGnoCiYeH             epds.events &= !EPollEventType::EPOLLWAKEUP.bits();
288*40609970SGnoCiYeH         }
289*40609970SGnoCiYeH 
290*40609970SGnoCiYeH         let events = EPollEventType::from_bits_truncate(epds.events);
291*40609970SGnoCiYeH 
292*40609970SGnoCiYeH         // 检查获取到的两个文件的正确性
293*40609970SGnoCiYeH         // 首先是不能自己嵌套自己
294*40609970SGnoCiYeH         // 然后ep_file必须是epoll文件
295*40609970SGnoCiYeH         if Arc::ptr_eq(&ep_file, &dst_file) || !Self::is_epoll_file(&ep_file) {
296*40609970SGnoCiYeH             return Err(SystemError::EINVAL);
297*40609970SGnoCiYeH         }
298*40609970SGnoCiYeH 
299*40609970SGnoCiYeH         if op != EPollCtlOption::EpollCtlDel && events.contains(EPollEventType::EPOLLEXCLUSIVE) {
300*40609970SGnoCiYeH             // epoll独占模式下不允许EpollCtlMod
301*40609970SGnoCiYeH             if op == EPollCtlOption::EpollCtlMod {
302*40609970SGnoCiYeH                 return Err(SystemError::EINVAL);
303*40609970SGnoCiYeH             }
304*40609970SGnoCiYeH 
305*40609970SGnoCiYeH             // 不支持嵌套的独占唤醒
306*40609970SGnoCiYeH             if op == EPollCtlOption::EpollCtlAdd && Self::is_epoll_file(&dst_file)
307*40609970SGnoCiYeH                 || !events
308*40609970SGnoCiYeH                     .difference(EPollEventType::EPOLLEXCLUSIVE_OK_BITS)
309*40609970SGnoCiYeH                     .is_empty()
310*40609970SGnoCiYeH             {
311*40609970SGnoCiYeH                 return Err(SystemError::EINVAL);
312*40609970SGnoCiYeH             }
313*40609970SGnoCiYeH         }
314*40609970SGnoCiYeH 
315*40609970SGnoCiYeH         // 从FilePrivateData获取到epoll
316*40609970SGnoCiYeH         if let FilePrivateData::EPoll(epoll_data) = &ep_file.lock_irqsave().private_data {
317*40609970SGnoCiYeH             let mut epoll_guard = {
318*40609970SGnoCiYeH                 if nonblock {
319*40609970SGnoCiYeH                     // 如果设置非阻塞,则尝试获取一次锁
320*40609970SGnoCiYeH                     if let Ok(guard) = epoll_data.epoll.0.try_lock_irqsave() {
321*40609970SGnoCiYeH                         guard
322*40609970SGnoCiYeH                     } else {
323*40609970SGnoCiYeH                         return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
324*40609970SGnoCiYeH                     }
325*40609970SGnoCiYeH                 } else {
326*40609970SGnoCiYeH                     epoll_data.epoll.0.lock_irqsave()
327*40609970SGnoCiYeH                 }
328*40609970SGnoCiYeH             };
329*40609970SGnoCiYeH 
330*40609970SGnoCiYeH             if op == EPollCtlOption::EpollCtlAdd {
331*40609970SGnoCiYeH                 // TODO: 循环检查是否为epoll嵌套epoll的情况,如果是则需要检测其深度
332*40609970SGnoCiYeH                 // 这里是需要一种检测算法的,但是目前未考虑epoll嵌套epoll的情况,所以暂时未实现
333*40609970SGnoCiYeH                 // Linux算法:https://code.dragonos.org.cn/xref/linux-6.1.9/fs/eventpoll.c?r=&mo=56953&fi=2057#2133
334*40609970SGnoCiYeH                 if Self::is_epoll_file(&dst_file) {
335*40609970SGnoCiYeH                     todo!();
336*40609970SGnoCiYeH                 }
337*40609970SGnoCiYeH             }
338*40609970SGnoCiYeH 
339*40609970SGnoCiYeH             let ep_item = epoll_guard.ep_items.get(&fd);
340*40609970SGnoCiYeH             match op {
341*40609970SGnoCiYeH                 EPollCtlOption::EpollCtlAdd => {
342*40609970SGnoCiYeH                     // 如果已经存在,则返回错误
343*40609970SGnoCiYeH                     if ep_item.is_some() {
344*40609970SGnoCiYeH                         return Err(SystemError::EEXIST);
345*40609970SGnoCiYeH                     }
346*40609970SGnoCiYeH                     // 设置epoll
347*40609970SGnoCiYeH                     let epitem = Arc::new(EPollItem::new(
348*40609970SGnoCiYeH                         Arc::downgrade(&epoll_data.epoll.0),
349*40609970SGnoCiYeH                         *epds,
350*40609970SGnoCiYeH                         fd,
351*40609970SGnoCiYeH                         Arc::downgrade(&dst_file),
352*40609970SGnoCiYeH                     ));
353*40609970SGnoCiYeH                     Self::ep_insert(&mut epoll_guard, dst_file, epitem)?;
354*40609970SGnoCiYeH                 }
355*40609970SGnoCiYeH                 EPollCtlOption::EpollCtlDel => {
356*40609970SGnoCiYeH                     // 不存在则返回错误
357*40609970SGnoCiYeH                     if ep_item.is_none() {
358*40609970SGnoCiYeH                         return Err(SystemError::ENOENT);
359*40609970SGnoCiYeH                     }
360*40609970SGnoCiYeH                     // 删除
361*40609970SGnoCiYeH                     Self::ep_remove(&mut epoll_guard, fd, Some(dst_file))?;
362*40609970SGnoCiYeH                 }
363*40609970SGnoCiYeH                 EPollCtlOption::EpollCtlMod => {
364*40609970SGnoCiYeH                     // 不存在则返回错误
365*40609970SGnoCiYeH                     if ep_item.is_none() {
366*40609970SGnoCiYeH                         return Err(SystemError::ENOENT);
367*40609970SGnoCiYeH                     }
368*40609970SGnoCiYeH                     let ep_item = ep_item.unwrap().clone();
369*40609970SGnoCiYeH                     if ep_item.event.read().events & EPollEventType::EPOLLEXCLUSIVE.bits() != 0 {
370*40609970SGnoCiYeH                         epds.events |=
371*40609970SGnoCiYeH                             EPollEventType::EPOLLERR.bits() | EPollEventType::EPOLLHUP.bits();
372*40609970SGnoCiYeH 
373*40609970SGnoCiYeH                         Self::ep_modify(&mut epoll_guard, ep_item, &epds)?;
374*40609970SGnoCiYeH                     }
375*40609970SGnoCiYeH                 }
376*40609970SGnoCiYeH             }
377*40609970SGnoCiYeH         }
378*40609970SGnoCiYeH 
379*40609970SGnoCiYeH         Ok(0)
380*40609970SGnoCiYeH     }
381*40609970SGnoCiYeH 
382*40609970SGnoCiYeH     /// ## epoll_wait的具体实现
383*40609970SGnoCiYeH     pub fn do_epoll_wait(
384*40609970SGnoCiYeH         epfd: i32,
385*40609970SGnoCiYeH         epoll_event: &mut [EPollEvent],
386*40609970SGnoCiYeH         max_events: i32,
387*40609970SGnoCiYeH         timespec: Option<TimeSpec>,
388*40609970SGnoCiYeH     ) -> Result<usize, SystemError> {
389*40609970SGnoCiYeH         let current_pcb = ProcessManager::current_pcb();
390*40609970SGnoCiYeH         let fd_table = current_pcb.fd_table();
391*40609970SGnoCiYeH         let fd_table_guard = fd_table.read();
392*40609970SGnoCiYeH 
393*40609970SGnoCiYeH         // 获取epoll文件
394*40609970SGnoCiYeH         let ep_file = fd_table_guard
395*40609970SGnoCiYeH             .get_file_by_fd(epfd)
396*40609970SGnoCiYeH             .ok_or(SystemError::EBADF)?;
397*40609970SGnoCiYeH 
398*40609970SGnoCiYeH         drop(fd_table_guard);
399*40609970SGnoCiYeH 
400*40609970SGnoCiYeH         // 确保是epoll file
401*40609970SGnoCiYeH         if !Self::is_epoll_file(&ep_file) {
402*40609970SGnoCiYeH             return Err(SystemError::EINVAL);
403*40609970SGnoCiYeH         }
404*40609970SGnoCiYeH 
405*40609970SGnoCiYeH         // 从epoll文件获取到epoll
406*40609970SGnoCiYeH         let mut epolldata = None;
407*40609970SGnoCiYeH         if let FilePrivateData::EPoll(epoll_data) = &ep_file.lock_irqsave().private_data {
408*40609970SGnoCiYeH             epolldata = Some(epoll_data.clone())
409*40609970SGnoCiYeH         }
410*40609970SGnoCiYeH         if epolldata.is_some() {
411*40609970SGnoCiYeH             let epoll_data = epolldata.unwrap();
412*40609970SGnoCiYeH             let epoll = epoll_data.epoll.clone();
413*40609970SGnoCiYeH             let epoll_guard = epoll.0.lock_irqsave();
414*40609970SGnoCiYeH 
415*40609970SGnoCiYeH             let mut timeout = false;
416*40609970SGnoCiYeH             if timespec.is_some() {
417*40609970SGnoCiYeH                 let timespec = timespec.unwrap();
418*40609970SGnoCiYeH                 if !(timespec.tv_sec > 0 || timespec.tv_nsec > 0) {
419*40609970SGnoCiYeH                     // 非阻塞情况
420*40609970SGnoCiYeH                     timeout = true;
421*40609970SGnoCiYeH                 }
422*40609970SGnoCiYeH             }
423*40609970SGnoCiYeH             // 判断epoll上有没有就绪事件
424*40609970SGnoCiYeH             let mut available = epoll_guard.ep_events_available();
425*40609970SGnoCiYeH             drop(epoll_guard);
426*40609970SGnoCiYeH             loop {
427*40609970SGnoCiYeH                 if available {
428*40609970SGnoCiYeH                     // 如果有就绪的事件,则直接返回就绪事件
429*40609970SGnoCiYeH                     return Self::ep_send_events(epoll.clone(), epoll_event, max_events);
430*40609970SGnoCiYeH                 }
431*40609970SGnoCiYeH 
432*40609970SGnoCiYeH                 if epoll.0.lock_irqsave().shutdown.load(Ordering::SeqCst) {
433*40609970SGnoCiYeH                     // 如果已经关闭
434*40609970SGnoCiYeH                     return Err(SystemError::EBADF);
435*40609970SGnoCiYeH                 }
436*40609970SGnoCiYeH 
437*40609970SGnoCiYeH                 // 如果超时
438*40609970SGnoCiYeH                 if timeout {
439*40609970SGnoCiYeH                     return Ok(0);
440*40609970SGnoCiYeH                 }
441*40609970SGnoCiYeH 
442*40609970SGnoCiYeH                 // 自旋等待一段时间
443*40609970SGnoCiYeH                 available = {
444*40609970SGnoCiYeH                     let mut ret = false;
445*40609970SGnoCiYeH                     for _ in 0..50 {
446*40609970SGnoCiYeH                         if let Ok(guard) = epoll.0.try_lock_irqsave() {
447*40609970SGnoCiYeH                             if guard.ep_events_available() {
448*40609970SGnoCiYeH                                 ret = true;
449*40609970SGnoCiYeH                                 break;
450*40609970SGnoCiYeH                             }
451*40609970SGnoCiYeH                         }
452*40609970SGnoCiYeH                     }
453*40609970SGnoCiYeH                     // 最后再次不使用try_lock尝试
454*40609970SGnoCiYeH                     if !ret {
455*40609970SGnoCiYeH                         ret = epoll.0.lock_irqsave().ep_events_available();
456*40609970SGnoCiYeH                     }
457*40609970SGnoCiYeH                     ret
458*40609970SGnoCiYeH                 };
459*40609970SGnoCiYeH 
460*40609970SGnoCiYeH                 if available {
461*40609970SGnoCiYeH                     continue;
462*40609970SGnoCiYeH                 }
463*40609970SGnoCiYeH 
464*40609970SGnoCiYeH                 // 如果有未处理的信号则返回错误
465*40609970SGnoCiYeH                 if current_pcb.sig_info().sig_pending().signal().bits() != 0 {
466*40609970SGnoCiYeH                     return Err(SystemError::EINTR);
467*40609970SGnoCiYeH                 }
468*40609970SGnoCiYeH 
469*40609970SGnoCiYeH                 // 还未等待到事件发生,则睡眠
470*40609970SGnoCiYeH                 // 注册定时器
471*40609970SGnoCiYeH                 let mut timer = None;
472*40609970SGnoCiYeH                 if timespec.is_some() {
473*40609970SGnoCiYeH                     let timespec = timespec.unwrap();
474*40609970SGnoCiYeH                     let handle = WakeUpHelper::new(current_pcb.clone());
475*40609970SGnoCiYeH                     let jiffies = next_n_us_timer_jiffies(
476*40609970SGnoCiYeH                         (timespec.tv_sec * 1000000 + timespec.tv_nsec / 1000) as u64,
477*40609970SGnoCiYeH                     );
478*40609970SGnoCiYeH                     let inner = Timer::new(handle, jiffies);
479*40609970SGnoCiYeH                     inner.activate();
480*40609970SGnoCiYeH                     timer = Some(inner);
481*40609970SGnoCiYeH                 }
482*40609970SGnoCiYeH                 let guard = epoll.0.lock_irqsave();
483*40609970SGnoCiYeH                 unsafe { guard.epoll_wq.sleep_without_schedule() };
484*40609970SGnoCiYeH                 drop(guard);
485*40609970SGnoCiYeH                 sched();
486*40609970SGnoCiYeH                 // 被唤醒后,检查是否有事件可读
487*40609970SGnoCiYeH                 available = epoll.0.lock_irqsave().ep_events_available();
488*40609970SGnoCiYeH                 if timer.is_some() {
489*40609970SGnoCiYeH                     if timer.as_ref().unwrap().timeout() {
490*40609970SGnoCiYeH                         // 超时
491*40609970SGnoCiYeH                         timeout = true;
492*40609970SGnoCiYeH                     } else {
493*40609970SGnoCiYeH                         // 未超时,则取消计时器
494*40609970SGnoCiYeH                         timer.unwrap().cancel();
495*40609970SGnoCiYeH                     }
496*40609970SGnoCiYeH                 }
497*40609970SGnoCiYeH             }
498*40609970SGnoCiYeH         } else {
499*40609970SGnoCiYeH             panic!("An epoll file does not have the corresponding private information");
500*40609970SGnoCiYeH         }
501*40609970SGnoCiYeH     }
502*40609970SGnoCiYeH 
503*40609970SGnoCiYeH     /// ## 将已经准备好的事件拷贝到用户空间
504*40609970SGnoCiYeH     ///
505*40609970SGnoCiYeH     /// ### 参数
506*40609970SGnoCiYeH     /// - epoll: 对应的epoll
507*40609970SGnoCiYeH     /// - user_event: 用户空间传入的epoll_event地址,因为内存对其问题,所以这里需要直接操作地址
508*40609970SGnoCiYeH     /// - max_events: 处理的最大事件数量
509*40609970SGnoCiYeH     fn ep_send_events(
510*40609970SGnoCiYeH         epoll: LockedEventPoll,
511*40609970SGnoCiYeH         user_event: &mut [EPollEvent],
512*40609970SGnoCiYeH         max_events: i32,
513*40609970SGnoCiYeH     ) -> Result<usize, SystemError> {
514*40609970SGnoCiYeH         let mut ep_guard = epoll.0.lock_irqsave();
515*40609970SGnoCiYeH         let mut res: usize = 0;
516*40609970SGnoCiYeH 
517*40609970SGnoCiYeH         // 在水平触发模式下,需要将epitem再次加入队列,在下次循环再次判断是否还有事件
518*40609970SGnoCiYeH         // (所以边缘触发的效率会高于水平触发,但是水平触发某些情况下能够使得更迅速地向用户反馈)
519*40609970SGnoCiYeH         let mut push_back = Vec::new();
520*40609970SGnoCiYeH         while let Some(epitem) = ep_guard.ready_list.pop_front() {
521*40609970SGnoCiYeH             if res >= max_events as usize {
522*40609970SGnoCiYeH                 push_back.push(epitem);
523*40609970SGnoCiYeH                 break;
524*40609970SGnoCiYeH             }
525*40609970SGnoCiYeH             let ep_events = EPollEventType::from_bits_truncate(epitem.event.read().events);
526*40609970SGnoCiYeH 
527*40609970SGnoCiYeH             // 再次poll获取事件(为了防止水平触发一直加入队列)
528*40609970SGnoCiYeH             let revents = epitem.ep_item_poll();
529*40609970SGnoCiYeH             if revents.is_empty() {
530*40609970SGnoCiYeH                 continue;
531*40609970SGnoCiYeH             }
532*40609970SGnoCiYeH 
533*40609970SGnoCiYeH             // 构建触发事件结构体
534*40609970SGnoCiYeH             let event = EPollEvent {
535*40609970SGnoCiYeH                 events: revents.bits,
536*40609970SGnoCiYeH                 data: epitem.event.read().data,
537*40609970SGnoCiYeH             };
538*40609970SGnoCiYeH 
539*40609970SGnoCiYeH             // 这里是需要判断下一个写入的位置是否为空指针
540*40609970SGnoCiYeH 
541*40609970SGnoCiYeH             // TODO:这里有可能会出现事件丢失的情况
542*40609970SGnoCiYeH             // 如果用户传入的数组长度小于传入的max_event,到这里时如果已经到数组最大长度,但是未到max_event
543*40609970SGnoCiYeH             // 会出现的问题是我们会把这个数据写入到后面的内存中,用户无法在传入的数组中拿到事件,而且写脏数据到了后面一片内存,导致事件丢失
544*40609970SGnoCiYeH             // 出现这个问题的几率比较小,首先是因为用户的使用不规范,后因为前面地址校验是按照max_event来校验的,只会在两块内存连着分配时出现,但是也是需要考虑的
545*40609970SGnoCiYeH 
546*40609970SGnoCiYeH             // 以下的写法判断并无意义,只是记一下错误处理
547*40609970SGnoCiYeH             // offset += core::mem::size_of::<EPollEvent>();
548*40609970SGnoCiYeH             // if offset >= max_offset {
549*40609970SGnoCiYeH             //     // 当前指向的地址已为空,则把epitem放回队列
550*40609970SGnoCiYeH             //     ep_guard.ready_list.push_back(epitem.clone());
551*40609970SGnoCiYeH             //     if res == 0 {
552*40609970SGnoCiYeH             //         // 一个都未写入成功,表明用户传进的地址就是有问题的
553*40609970SGnoCiYeH             //         return Err(SystemError::EFAULT);
554*40609970SGnoCiYeH             //     }
555*40609970SGnoCiYeH             // }
556*40609970SGnoCiYeH 
557*40609970SGnoCiYeH             // 拷贝到用户空间
558*40609970SGnoCiYeH             user_event[res] = event;
559*40609970SGnoCiYeH             // 记数加一
560*40609970SGnoCiYeH             res += 1;
561*40609970SGnoCiYeH 
562*40609970SGnoCiYeH             // crate::kdebug!("ep send {event:?}");
563*40609970SGnoCiYeH 
564*40609970SGnoCiYeH             if ep_events.contains(EPollEventType::EPOLLONESHOT) {
565*40609970SGnoCiYeH                 let mut event_writer = epitem.event.write();
566*40609970SGnoCiYeH                 let new_event = event_writer.events & EPollEventType::EP_PRIVATE_BITS.bits;
567*40609970SGnoCiYeH                 event_writer.set_events(new_event);
568*40609970SGnoCiYeH             } else if !ep_events.contains(EPollEventType::EPOLLET) {
569*40609970SGnoCiYeH                 push_back.push(epitem);
570*40609970SGnoCiYeH             }
571*40609970SGnoCiYeH         }
572*40609970SGnoCiYeH 
573*40609970SGnoCiYeH         for item in push_back {
574*40609970SGnoCiYeH             ep_guard.ep_add_ready(item);
575*40609970SGnoCiYeH         }
576*40609970SGnoCiYeH 
577*40609970SGnoCiYeH         Ok(res)
578*40609970SGnoCiYeH     }
579*40609970SGnoCiYeH 
580*40609970SGnoCiYeH     // ### 查看文件是否为epoll文件
581*40609970SGnoCiYeH     fn is_epoll_file(file: &Arc<SpinLock<File>>) -> bool {
582*40609970SGnoCiYeH         if let FilePrivateData::EPoll(_) = file.lock_irqsave().private_data {
583*40609970SGnoCiYeH             return true;
584*40609970SGnoCiYeH         }
585*40609970SGnoCiYeH         return false;
586*40609970SGnoCiYeH     }
587*40609970SGnoCiYeH 
588*40609970SGnoCiYeH     fn ep_insert(
589*40609970SGnoCiYeH         epoll_guard: &mut SpinLockGuard<EventPoll>,
590*40609970SGnoCiYeH         dst_file: Arc<SpinLock<File>>,
591*40609970SGnoCiYeH         epitem: Arc<EPollItem>,
592*40609970SGnoCiYeH     ) -> Result<(), SystemError> {
593*40609970SGnoCiYeH         if Self::is_epoll_file(&dst_file) {
594*40609970SGnoCiYeH             return Err(SystemError::ENOSYS);
595*40609970SGnoCiYeH             // TODO:现在的实现先不考虑嵌套其它类型的文件(暂时只针对socket),这里的嵌套指epoll/select/poll
596*40609970SGnoCiYeH         }
597*40609970SGnoCiYeH 
598*40609970SGnoCiYeH         let test_poll = dst_file.lock_irqsave().poll();
599*40609970SGnoCiYeH         if test_poll.is_err() {
600*40609970SGnoCiYeH             if test_poll.unwrap_err() == SystemError::EOPNOTSUPP_OR_ENOTSUP {
601*40609970SGnoCiYeH                 // 如果目标文件不支持poll
602*40609970SGnoCiYeH                 return Err(SystemError::ENOSYS);
603*40609970SGnoCiYeH             }
604*40609970SGnoCiYeH         }
605*40609970SGnoCiYeH 
606*40609970SGnoCiYeH         epoll_guard.ep_items.insert(epitem.fd, epitem.clone());
607*40609970SGnoCiYeH 
608*40609970SGnoCiYeH         // 检查文件是否已经有事件发生
609*40609970SGnoCiYeH         let event = epitem.ep_item_poll();
610*40609970SGnoCiYeH         if !event.is_empty() {
611*40609970SGnoCiYeH             // 加入到就绪队列
612*40609970SGnoCiYeH             epoll_guard.ep_add_ready(epitem.clone());
613*40609970SGnoCiYeH 
614*40609970SGnoCiYeH             epoll_guard.ep_wake_one();
615*40609970SGnoCiYeH         }
616*40609970SGnoCiYeH 
617*40609970SGnoCiYeH         // TODO: 嵌套epoll?
618*40609970SGnoCiYeH 
619*40609970SGnoCiYeH         // 这个标志是用与电源管理相关,暂时不支持
620*40609970SGnoCiYeH         if epitem.event.read().events & EPollEventType::EPOLLWAKEUP.bits() != 0 {
621*40609970SGnoCiYeH             return Err(SystemError::ENOSYS);
622*40609970SGnoCiYeH         }
623*40609970SGnoCiYeH 
624*40609970SGnoCiYeH         dst_file.lock_irqsave().add_epoll(epitem.clone())?;
625*40609970SGnoCiYeH         Ok(())
626*40609970SGnoCiYeH     }
627*40609970SGnoCiYeH 
628*40609970SGnoCiYeH     pub fn ep_remove(
629*40609970SGnoCiYeH         epoll: &mut SpinLockGuard<EventPoll>,
630*40609970SGnoCiYeH         fd: i32,
631*40609970SGnoCiYeH         dst_file: Option<Arc<SpinLock<File>>>,
632*40609970SGnoCiYeH     ) -> Result<(), SystemError> {
633*40609970SGnoCiYeH         if dst_file.is_some() {
634*40609970SGnoCiYeH             let dst_file = dst_file.unwrap();
635*40609970SGnoCiYeH             let mut file_guard = dst_file.lock_irqsave();
636*40609970SGnoCiYeH 
637*40609970SGnoCiYeH             file_guard.remove_epoll(epoll.self_ref.as_ref().unwrap())?;
638*40609970SGnoCiYeH         }
639*40609970SGnoCiYeH 
640*40609970SGnoCiYeH         let epitem = epoll.ep_items.remove(&fd).unwrap();
641*40609970SGnoCiYeH 
642*40609970SGnoCiYeH         let _ = epoll
643*40609970SGnoCiYeH             .ready_list
644*40609970SGnoCiYeH             .extract_if(|item| Arc::ptr_eq(item, &epitem));
645*40609970SGnoCiYeH 
646*40609970SGnoCiYeH         Ok(())
647*40609970SGnoCiYeH     }
648*40609970SGnoCiYeH 
649*40609970SGnoCiYeH     /// ## 修改已经注册的监听事件
650*40609970SGnoCiYeH     ///
651*40609970SGnoCiYeH     /// ### 参数
652*40609970SGnoCiYeH     /// - epoll_guard: EventPoll的锁
653*40609970SGnoCiYeH     /// - epitem: 需要修改的描述符对应的epitem
654*40609970SGnoCiYeH     /// - event: 新的事件
655*40609970SGnoCiYeH     fn ep_modify(
656*40609970SGnoCiYeH         epoll_guard: &mut SpinLockGuard<EventPoll>,
657*40609970SGnoCiYeH         epitem: Arc<EPollItem>,
658*40609970SGnoCiYeH         event: &EPollEvent,
659*40609970SGnoCiYeH     ) -> Result<(), SystemError> {
660*40609970SGnoCiYeH         let mut epi_event_guard = epitem.event.write();
661*40609970SGnoCiYeH 
662*40609970SGnoCiYeH         // 修改epitem
663*40609970SGnoCiYeH         epi_event_guard.events = event.events;
664*40609970SGnoCiYeH         epi_event_guard.data = event.data;
665*40609970SGnoCiYeH 
666*40609970SGnoCiYeH         drop(epi_event_guard);
667*40609970SGnoCiYeH         // 修改后检查文件是否已经有感兴趣事件发生
668*40609970SGnoCiYeH         let event = epitem.ep_item_poll();
669*40609970SGnoCiYeH         if !event.is_empty() {
670*40609970SGnoCiYeH             epoll_guard.ep_add_ready(epitem.clone());
671*40609970SGnoCiYeH 
672*40609970SGnoCiYeH             epoll_guard.ep_wake_one();
673*40609970SGnoCiYeH         }
674*40609970SGnoCiYeH         // TODO:处理EPOLLWAKEUP,目前不支持
675*40609970SGnoCiYeH 
676*40609970SGnoCiYeH         Ok(())
677*40609970SGnoCiYeH     }
678*40609970SGnoCiYeH 
679*40609970SGnoCiYeH     /// ### 判断epoll是否有就绪item
680*40609970SGnoCiYeH     pub fn ep_events_available(&self) -> bool {
681*40609970SGnoCiYeH         !self.ready_list.is_empty()
682*40609970SGnoCiYeH     }
683*40609970SGnoCiYeH 
684*40609970SGnoCiYeH     /// ### 将epitem加入到就绪队列,如果为重复添加则忽略
685*40609970SGnoCiYeH     pub fn ep_add_ready(&mut self, epitem: Arc<EPollItem>) {
686*40609970SGnoCiYeH         let ret = self.ready_list.iter().find(|epi| Arc::ptr_eq(epi, &epitem));
687*40609970SGnoCiYeH 
688*40609970SGnoCiYeH         if ret.is_none() {
689*40609970SGnoCiYeH             self.ready_list.push_back(epitem);
690*40609970SGnoCiYeH         }
691*40609970SGnoCiYeH     }
692*40609970SGnoCiYeH 
693*40609970SGnoCiYeH     /// ### 判断该epoll上是否有进程在等待
694*40609970SGnoCiYeH     pub fn ep_has_waiter(&self) -> bool {
695*40609970SGnoCiYeH         self.epoll_wq.len() != 0
696*40609970SGnoCiYeH     }
697*40609970SGnoCiYeH 
698*40609970SGnoCiYeH     /// ### 唤醒所有在epoll上等待的进程
699*40609970SGnoCiYeH     pub fn ep_wake_all(&self) {
700*40609970SGnoCiYeH         self.epoll_wq.wakeup_all(None);
701*40609970SGnoCiYeH     }
702*40609970SGnoCiYeH 
703*40609970SGnoCiYeH     /// ### 唤醒所有在epoll上等待的首个进程
704*40609970SGnoCiYeH     pub fn ep_wake_one(&self) {
705*40609970SGnoCiYeH         self.epoll_wq.wakeup(None);
706*40609970SGnoCiYeH     }
707*40609970SGnoCiYeH }
708*40609970SGnoCiYeH 
709*40609970SGnoCiYeH /// 与C兼容的Epoll事件结构体
710*40609970SGnoCiYeH #[derive(Copy, Clone, Default)]
711*40609970SGnoCiYeH #[repr(packed)]
712*40609970SGnoCiYeH pub struct EPollEvent {
713*40609970SGnoCiYeH     /// 表示触发的事件
714*40609970SGnoCiYeH     events: u32,
715*40609970SGnoCiYeH     /// 内核态不使用该字段,该字段由用户态自由使用,在事件发生时内核将会原样返回
716*40609970SGnoCiYeH     data: u64,
717*40609970SGnoCiYeH }
718*40609970SGnoCiYeH 
719*40609970SGnoCiYeH impl Debug for EPollEvent {
720*40609970SGnoCiYeH     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
721*40609970SGnoCiYeH         let events = self.events;
722*40609970SGnoCiYeH         let u64 = self.data;
723*40609970SGnoCiYeH         f.debug_struct("epoll_event")
724*40609970SGnoCiYeH             .field("events", &events)
725*40609970SGnoCiYeH             .field("data", &u64)
726*40609970SGnoCiYeH             .finish()
727*40609970SGnoCiYeH     }
728*40609970SGnoCiYeH }
729*40609970SGnoCiYeH 
730*40609970SGnoCiYeH impl EPollEvent {
731*40609970SGnoCiYeH     pub fn set_events(&mut self, events: u32) {
732*40609970SGnoCiYeH         self.events = events;
733*40609970SGnoCiYeH     }
734*40609970SGnoCiYeH 
735*40609970SGnoCiYeH     pub fn events(&self) -> u32 {
736*40609970SGnoCiYeH         self.events
737*40609970SGnoCiYeH     }
738*40609970SGnoCiYeH }
739*40609970SGnoCiYeH 
740*40609970SGnoCiYeH /// ## epoll_ctl函数的参数
741*40609970SGnoCiYeH #[derive(Debug, PartialEq)]
742*40609970SGnoCiYeH pub enum EPollCtlOption {
743*40609970SGnoCiYeH     /// 注册新的文件描述符到epfd
744*40609970SGnoCiYeH     EpollCtlAdd,
745*40609970SGnoCiYeH     /// 将对应的文件描述符从epfd中删除
746*40609970SGnoCiYeH     EpollCtlDel,
747*40609970SGnoCiYeH     /// 修改已经注册的文件描述符的监听事件
748*40609970SGnoCiYeH     EpollCtlMod,
749*40609970SGnoCiYeH }
750*40609970SGnoCiYeH 
751*40609970SGnoCiYeH impl EPollCtlOption {
752*40609970SGnoCiYeH     pub fn from_op_num(op: usize) -> Result<Self, SystemError> {
753*40609970SGnoCiYeH         match op {
754*40609970SGnoCiYeH             1 => Ok(Self::EpollCtlAdd),
755*40609970SGnoCiYeH             2 => Ok(Self::EpollCtlDel),
756*40609970SGnoCiYeH             3 => Ok(Self::EpollCtlMod),
757*40609970SGnoCiYeH             _ => Err(SystemError::EINVAL),
758*40609970SGnoCiYeH         }
759*40609970SGnoCiYeH     }
760*40609970SGnoCiYeH }
761*40609970SGnoCiYeH 
762*40609970SGnoCiYeH bitflags! {
763*40609970SGnoCiYeH     #[allow(dead_code)]
764*40609970SGnoCiYeH     pub struct EPollEventType: u32 {
765*40609970SGnoCiYeH         /// 对应的描述符有新的数据可读时会触发
766*40609970SGnoCiYeH         const EPOLLIN = 0x00000001;
767*40609970SGnoCiYeH         /// 对应的描述符有紧急数据可读时会触发
768*40609970SGnoCiYeH         const EPOLLPRI = 0x00000002;
769*40609970SGnoCiYeH         /// 对应的描述符可以写入数据时会触发
770*40609970SGnoCiYeH         const EPOLLOUT = 0x00000004;
771*40609970SGnoCiYeH         /// 对应的描述符发生错误时会触发
772*40609970SGnoCiYeH         const EPOLLERR = 0x00000008;
773*40609970SGnoCiYeH         /// 对应的描述符被挂断(连接关闭)时会触发
774*40609970SGnoCiYeH         const EPOLLHUP = 0x00000010;
775*40609970SGnoCiYeH         /// 对应的描述符不是一个有效的文件描述符时会触发
776*40609970SGnoCiYeH         const EPOLLNVAL = 0x00000020;
777*40609970SGnoCiYeH         /// 普通数据可读,类似于`EPOLLIN`
778*40609970SGnoCiYeH         const EPOLLRDNORM = 0x00000040;
779*40609970SGnoCiYeH         /// 优先级带外数据可读
780*40609970SGnoCiYeH         const EPOLLRDBAND = 0x00000080;
781*40609970SGnoCiYeH         /// 普通数据可写,类似于'EPOLLOUT'
782*40609970SGnoCiYeH         const EPOLLWRNORM = 0x00000100;
783*40609970SGnoCiYeH         /// 优先级带外数据可写
784*40609970SGnoCiYeH         const EPOLLWRBAND = 0x00000200;
785*40609970SGnoCiYeH         /// 通过消息队列收到消息时会触
786*40609970SGnoCiYeH         const EPOLLMSG = 0x00000400;
787*40609970SGnoCiYeH         /// 对应的描述符被挂断(连接关闭)的一端发送了 FIN 时会触发(读关闭)
788*40609970SGnoCiYeH         const EPOLLRDHUP = 0x00002000;
789*40609970SGnoCiYeH 
790*40609970SGnoCiYeH         /// 以下为额外选项
791*40609970SGnoCiYeH         ///
792*40609970SGnoCiYeH         /// 特定选项,用于异步 I/O,目前未实现
793*40609970SGnoCiYeH         const EPOLL_URING_WAKE = 1u32 << 27;
794*40609970SGnoCiYeH         /// 设置epoll为独占模式
795*40609970SGnoCiYeH         const EPOLLEXCLUSIVE = 1u32 << 28;
796*40609970SGnoCiYeH         ///  允许在系统挂起时唤醒 epoll,通常用于通过 eventfd 或 timerfd 唤醒 epoll,(通常与电源管理相关,未实现)
797*40609970SGnoCiYeH         const EPOLLWAKEUP = 1u32 << 29;
798*40609970SGnoCiYeH         /// 表示只监听一次事件,之后需要重新添加
799*40609970SGnoCiYeH         const EPOLLONESHOT = 1u32 << 30;
800*40609970SGnoCiYeH 
801*40609970SGnoCiYeH         /// 启用边缘触发模式(即只有下次触发事件时才会通过epoll_wait返回),
802*40609970SGnoCiYeH         /// 对应为水平触发(默认),水平触发模式下若这次未处理完数据,那epoll还会将其加入自己的就绪队列
803*40609970SGnoCiYeH         const EPOLLET = 1u32 << 31;
804*40609970SGnoCiYeH 
805*40609970SGnoCiYeH         /// 以下为组合码
806*40609970SGnoCiYeH         const EPOLLINOUT_BITS = Self::EPOLLIN.bits | Self::EPOLLOUT.bits;
807*40609970SGnoCiYeH         const EPOLLEXCLUSIVE_OK_BITS =
808*40609970SGnoCiYeH             Self::EPOLLINOUT_BITS.bits
809*40609970SGnoCiYeH             | Self::EPOLLERR.bits
810*40609970SGnoCiYeH             | Self::EPOLLHUP.bits
811*40609970SGnoCiYeH             | Self::EPOLLWAKEUP.bits
812*40609970SGnoCiYeH             | Self::EPOLLET.bits
813*40609970SGnoCiYeH             | Self::EPOLLEXCLUSIVE.bits;
814*40609970SGnoCiYeH 
815*40609970SGnoCiYeH         const EP_PRIVATE_BITS =
816*40609970SGnoCiYeH             Self::EPOLLWAKEUP.bits
817*40609970SGnoCiYeH             | Self::EPOLLONESHOT.bits
818*40609970SGnoCiYeH             | Self::EPOLLET.bits
819*40609970SGnoCiYeH             | Self::EPOLLEXCLUSIVE.bits;
820*40609970SGnoCiYeH 
821*40609970SGnoCiYeH         /// 表示epoll已经被释放,但是在目前的设计中未用到
822*40609970SGnoCiYeH         const POLLFREE = 0x4000;
823*40609970SGnoCiYeH     }
824*40609970SGnoCiYeH }
825