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