140609970SGnoCiYeH use core::{ 2415e14e9Slaokengwt any::Any, 340609970SGnoCiYeH fmt::Debug, 440609970SGnoCiYeH sync::atomic::{AtomicBool, Ordering}, 540609970SGnoCiYeH }; 640609970SGnoCiYeH 740609970SGnoCiYeH use alloc::{ 840609970SGnoCiYeH collections::LinkedList, 940609970SGnoCiYeH sync::{Arc, Weak}, 1040609970SGnoCiYeH vec::Vec, 1140609970SGnoCiYeH }; 12415e14e9Slaokengwt use intertrait::CastFromSync; 1391e9d4abSLoGin use system_error::SystemError; 1440609970SGnoCiYeH 1540609970SGnoCiYeH use crate::{ 1640609970SGnoCiYeH filesystem::vfs::{ 1740609970SGnoCiYeH file::{File, FileMode}, 1840609970SGnoCiYeH FilePrivateData, IndexNode, Metadata, 1940609970SGnoCiYeH }, 2040609970SGnoCiYeH libs::{ 2140609970SGnoCiYeH rbtree::RBTree, 2240609970SGnoCiYeH rwlock::RwLock, 2340609970SGnoCiYeH spinlock::{SpinLock, SpinLockGuard}, 2440609970SGnoCiYeH wait_queue::WaitQueue, 2540609970SGnoCiYeH }, 2640609970SGnoCiYeH process::ProcessManager, 27f0c87a89SGnoCiYeH sched::{schedule, SchedMode}, 2840609970SGnoCiYeH time::{ 2940609970SGnoCiYeH timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper}, 306fc066acSJomo PosixTimeSpec, 3140609970SGnoCiYeH }, 3240609970SGnoCiYeH }; 3340609970SGnoCiYeH 3440609970SGnoCiYeH pub mod syscall; 3540609970SGnoCiYeH 3640609970SGnoCiYeH #[derive(Debug, Clone)] 3740609970SGnoCiYeH pub struct LockedEventPoll(Arc<SpinLock<EventPoll>>); 3840609970SGnoCiYeH 3940609970SGnoCiYeH /// 内核的Epoll对象结构体,当用户创建一个Epoll时,内核就会创建一个该类型对象 4040609970SGnoCiYeH /// 它对应一个epfd 4140609970SGnoCiYeH #[derive(Debug)] 4240609970SGnoCiYeH pub struct EventPoll { 4340609970SGnoCiYeH /// epoll_wait用到的等待队列 4440609970SGnoCiYeH epoll_wq: WaitQueue, 4540609970SGnoCiYeH /// 维护所有添加进来的socket的红黑树 4640609970SGnoCiYeH ep_items: RBTree<i32, Arc<EPollItem>>, 4740609970SGnoCiYeH /// 接收就绪的描述符列表 4840609970SGnoCiYeH ready_list: LinkedList<Arc<EPollItem>>, 4940609970SGnoCiYeH /// 是否已经关闭 5040609970SGnoCiYeH shutdown: AtomicBool, 5140609970SGnoCiYeH self_ref: Option<Weak<SpinLock<EventPoll>>>, 5240609970SGnoCiYeH } 5340609970SGnoCiYeH 5440609970SGnoCiYeH impl EventPoll { 55*2b7818e8SLoGin pub const EP_MAX_EVENTS: u32 = u32::MAX / (core::mem::size_of::<EPollEvent>() as u32); 5652bcb59eSGnoCiYeH /// 用于获取inode中的epitem队列 5752bcb59eSGnoCiYeH pub const ADD_EPOLLITEM: u32 = 0x7965; 5840609970SGnoCiYeH pub fn new() -> Self { 5940609970SGnoCiYeH Self { 60b5b571e0SLoGin epoll_wq: WaitQueue::default(), 6140609970SGnoCiYeH ep_items: RBTree::new(), 6240609970SGnoCiYeH ready_list: LinkedList::new(), 6340609970SGnoCiYeH shutdown: AtomicBool::new(false), 6440609970SGnoCiYeH self_ref: None, 6540609970SGnoCiYeH } 6640609970SGnoCiYeH } 6740609970SGnoCiYeH } 6840609970SGnoCiYeH 69b5b571e0SLoGin impl Default for EventPoll { 70b5b571e0SLoGin fn default() -> Self { 71b5b571e0SLoGin Self::new() 72b5b571e0SLoGin } 73b5b571e0SLoGin } 74b5b571e0SLoGin 7540609970SGnoCiYeH /// EpollItem表示的是Epoll所真正管理的对象 7640609970SGnoCiYeH /// 每当用户向Epoll添加描述符时都会注册一个新的EpollItem,EpollItem携带了一些被监听的描述符的必要信息 7740609970SGnoCiYeH #[derive(Debug)] 7840609970SGnoCiYeH pub struct EPollItem { 7940609970SGnoCiYeH /// 对应的Epoll 8040609970SGnoCiYeH epoll: Weak<SpinLock<EventPoll>>, 8140609970SGnoCiYeH /// 用户注册的事件 8240609970SGnoCiYeH event: RwLock<EPollEvent>, 8340609970SGnoCiYeH /// 监听的描述符 8440609970SGnoCiYeH fd: i32, 8540609970SGnoCiYeH /// 对应的文件 86dfe53cf0SGnoCiYeH file: Weak<File>, 8740609970SGnoCiYeH } 8840609970SGnoCiYeH 8940609970SGnoCiYeH impl EPollItem { 9040609970SGnoCiYeH pub fn new( 9140609970SGnoCiYeH epoll: Weak<SpinLock<EventPoll>>, 9240609970SGnoCiYeH events: EPollEvent, 9340609970SGnoCiYeH fd: i32, 94dfe53cf0SGnoCiYeH file: Weak<File>, 9540609970SGnoCiYeH ) -> Self { 9640609970SGnoCiYeH Self { 9740609970SGnoCiYeH epoll, 9840609970SGnoCiYeH event: RwLock::new(events), 9940609970SGnoCiYeH fd, 10040609970SGnoCiYeH file, 10140609970SGnoCiYeH } 10240609970SGnoCiYeH } 10340609970SGnoCiYeH 10440609970SGnoCiYeH pub fn epoll(&self) -> Weak<SpinLock<EventPoll>> { 10540609970SGnoCiYeH self.epoll.clone() 10640609970SGnoCiYeH } 10740609970SGnoCiYeH 10840609970SGnoCiYeH pub fn event(&self) -> &RwLock<EPollEvent> { 10940609970SGnoCiYeH &self.event 11040609970SGnoCiYeH } 11140609970SGnoCiYeH 112dfe53cf0SGnoCiYeH pub fn file(&self) -> Weak<File> { 11340609970SGnoCiYeH self.file.clone() 11440609970SGnoCiYeH } 11540609970SGnoCiYeH 11640609970SGnoCiYeH pub fn fd(&self) -> i32 { 11740609970SGnoCiYeH self.fd 11840609970SGnoCiYeH } 11940609970SGnoCiYeH 12040609970SGnoCiYeH /// ## 通过epoll_item来执行绑定文件的poll方法,并获取到感兴趣的事件 12140609970SGnoCiYeH fn ep_item_poll(&self) -> EPollEventType { 12240609970SGnoCiYeH let file = self.file.upgrade(); 12340609970SGnoCiYeH if file.is_none() { 12440609970SGnoCiYeH return EPollEventType::empty(); 12540609970SGnoCiYeH } 126dfe53cf0SGnoCiYeH if let Ok(events) = file.unwrap().poll() { 12740609970SGnoCiYeH let events = events as u32 & self.event.read().events; 12840609970SGnoCiYeH return EPollEventType::from_bits_truncate(events); 12940609970SGnoCiYeH } 13040609970SGnoCiYeH return EPollEventType::empty(); 13140609970SGnoCiYeH } 13240609970SGnoCiYeH } 13340609970SGnoCiYeH 134415e14e9Slaokengwt pub trait KernelIoctlData: Send + Sync + Any + Debug + CastFromSync {} 135415e14e9Slaokengwt 136415e14e9Slaokengwt impl KernelIoctlData for EPollItem {} 137415e14e9Slaokengwt 13840609970SGnoCiYeH /// ### Epoll文件的私有信息 13940609970SGnoCiYeH #[derive(Debug, Clone)] 14040609970SGnoCiYeH pub struct EPollPrivateData { 14140609970SGnoCiYeH epoll: LockedEventPoll, 14240609970SGnoCiYeH } 14340609970SGnoCiYeH 14440609970SGnoCiYeH /// ### 该结构体将Epoll加入文件系统 14540609970SGnoCiYeH #[derive(Debug)] 14640609970SGnoCiYeH pub struct EPollInode { 14740609970SGnoCiYeH epoll: LockedEventPoll, 14840609970SGnoCiYeH } 14940609970SGnoCiYeH 15040609970SGnoCiYeH impl EPollInode { 15140609970SGnoCiYeH pub fn new(epoll: LockedEventPoll) -> Arc<Self> { 15240609970SGnoCiYeH Arc::new(Self { epoll }) 15340609970SGnoCiYeH } 15440609970SGnoCiYeH } 15540609970SGnoCiYeH 15640609970SGnoCiYeH impl IndexNode for EPollInode { 15740609970SGnoCiYeH fn read_at( 15840609970SGnoCiYeH &self, 15940609970SGnoCiYeH _offset: usize, 16040609970SGnoCiYeH _len: usize, 16140609970SGnoCiYeH _buf: &mut [u8], 162dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>, 16391e9d4abSLoGin ) -> Result<usize, SystemError> { 16440609970SGnoCiYeH Err(SystemError::ENOSYS) 16540609970SGnoCiYeH } 16640609970SGnoCiYeH 16740609970SGnoCiYeH fn write_at( 16840609970SGnoCiYeH &self, 16940609970SGnoCiYeH _offset: usize, 17040609970SGnoCiYeH _len: usize, 17140609970SGnoCiYeH _buf: &[u8], 172dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>, 17391e9d4abSLoGin ) -> Result<usize, SystemError> { 17440609970SGnoCiYeH Err(SystemError::ENOSYS) 17540609970SGnoCiYeH } 17640609970SGnoCiYeH 1775e948c56SGnoCiYeH fn poll(&self, _private_data: &FilePrivateData) -> Result<usize, SystemError> { 17840609970SGnoCiYeH // 需要实现epoll嵌套epoll时,需要实现这里 17940609970SGnoCiYeH todo!() 18040609970SGnoCiYeH } 18140609970SGnoCiYeH 18240609970SGnoCiYeH fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> { 18340609970SGnoCiYeH todo!() 18440609970SGnoCiYeH } 18540609970SGnoCiYeH 18640609970SGnoCiYeH fn as_any_ref(&self) -> &dyn core::any::Any { 18740609970SGnoCiYeH self 18840609970SGnoCiYeH } 18940609970SGnoCiYeH 19091e9d4abSLoGin fn list(&self) -> Result<Vec<alloc::string::String>, SystemError> { 19140609970SGnoCiYeH Err(SystemError::ENOSYS) 19240609970SGnoCiYeH } 19340609970SGnoCiYeH 19440609970SGnoCiYeH fn metadata(&self) -> Result<Metadata, SystemError> { 19540609970SGnoCiYeH Ok(Metadata::default()) 19640609970SGnoCiYeH } 19740609970SGnoCiYeH 198dfe53cf0SGnoCiYeH fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 19940609970SGnoCiYeH // 释放资源 20040609970SGnoCiYeH let mut epoll = self.epoll.0.lock_irqsave(); 20140609970SGnoCiYeH 20240609970SGnoCiYeH // 唤醒epoll上面等待的所有进程 20340609970SGnoCiYeH epoll.shutdown.store(true, Ordering::SeqCst); 20440609970SGnoCiYeH epoll.ep_wake_all(); 20540609970SGnoCiYeH 20640609970SGnoCiYeH let fds = epoll.ep_items.keys().cloned().collect::<Vec<_>>(); 20740609970SGnoCiYeH 20840609970SGnoCiYeH // 清理红黑树里面的epitems 20940609970SGnoCiYeH for fd in fds { 21040609970SGnoCiYeH let file = ProcessManager::current_pcb() 21140609970SGnoCiYeH .fd_table() 21240609970SGnoCiYeH .read() 21340609970SGnoCiYeH .get_file_by_fd(fd); 21440609970SGnoCiYeH 21540609970SGnoCiYeH if file.is_some() { 216dfe53cf0SGnoCiYeH file.unwrap().remove_epoll(&Arc::downgrade(&self.epoll.0))?; 21740609970SGnoCiYeH } 21840609970SGnoCiYeH 21940609970SGnoCiYeH epoll.ep_items.remove(&fd); 22040609970SGnoCiYeH } 22140609970SGnoCiYeH 22240609970SGnoCiYeH Ok(()) 22340609970SGnoCiYeH } 22440609970SGnoCiYeH 225dfe53cf0SGnoCiYeH fn open( 226dfe53cf0SGnoCiYeH &self, 227dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>, 228dfe53cf0SGnoCiYeH _mode: &FileMode, 229dfe53cf0SGnoCiYeH ) -> Result<(), SystemError> { 23040609970SGnoCiYeH Ok(()) 23140609970SGnoCiYeH } 23240609970SGnoCiYeH } 23340609970SGnoCiYeH 23440609970SGnoCiYeH impl EventPoll { 23540609970SGnoCiYeH /// ## 创建epoll对象 23640609970SGnoCiYeH /// 23740609970SGnoCiYeH /// ### 参数 23840609970SGnoCiYeH /// - flags: 创建的epoll文件的FileMode 23940609970SGnoCiYeH /// 24040609970SGnoCiYeH /// ### 返回值 24140609970SGnoCiYeH /// - 成功则返回Ok(fd),否则返回Err 24240609970SGnoCiYeH pub fn do_create_epoll(flags: FileMode) -> Result<usize, SystemError> { 24340609970SGnoCiYeH if !flags.difference(FileMode::O_CLOEXEC).is_empty() { 24440609970SGnoCiYeH return Err(SystemError::EINVAL); 24540609970SGnoCiYeH } 24640609970SGnoCiYeH 24740609970SGnoCiYeH // 创建epoll 24840609970SGnoCiYeH let epoll = LockedEventPoll(Arc::new(SpinLock::new(EventPoll::new()))); 24940609970SGnoCiYeH epoll.0.lock_irqsave().self_ref = Some(Arc::downgrade(&epoll.0)); 25040609970SGnoCiYeH 25140609970SGnoCiYeH // 创建epoll的inode对象 25240609970SGnoCiYeH let epoll_inode = EPollInode::new(epoll.clone()); 25340609970SGnoCiYeH 25440609970SGnoCiYeH let mut ep_file = File::new( 25540609970SGnoCiYeH epoll_inode, 25640609970SGnoCiYeH FileMode::O_RDWR | (flags & FileMode::O_CLOEXEC), 25740609970SGnoCiYeH )?; 25840609970SGnoCiYeH 25940609970SGnoCiYeH // 设置ep_file的FilePrivateData 260dfe53cf0SGnoCiYeH ep_file.private_data = SpinLock::new(FilePrivateData::EPoll(EPollPrivateData { epoll })); 26140609970SGnoCiYeH 26240609970SGnoCiYeH let current_pcb = ProcessManager::current_pcb(); 26340609970SGnoCiYeH let fd_table = current_pcb.fd_table(); 26440609970SGnoCiYeH let mut fd_table_guard = fd_table.write(); 26540609970SGnoCiYeH 26640609970SGnoCiYeH let fd = fd_table_guard.alloc_fd(ep_file, None)?; 26740609970SGnoCiYeH 26840609970SGnoCiYeH Ok(fd as usize) 26940609970SGnoCiYeH } 27040609970SGnoCiYeH 27140609970SGnoCiYeH /// ## epoll_ctl的具体实现 27240609970SGnoCiYeH /// 27340609970SGnoCiYeH /// 根据不同的op对epoll文件进行增删改 27440609970SGnoCiYeH /// 27540609970SGnoCiYeH /// ### 参数 27640609970SGnoCiYeH /// - epfd: 操作的epoll文件描述符 27740609970SGnoCiYeH /// - op: 对应的操作 27840609970SGnoCiYeH /// - fd: 操作对应的文件描述符 27940609970SGnoCiYeH /// - epds: 从用户态传入的event,若op为EpollCtlAdd,则对应注册的监听事件,若op为EPollCtlMod,则对应更新的事件,删除操作不涉及此字段 28040609970SGnoCiYeH /// - nonblock: 定义这次操作是否为非阻塞(有可能其他地方占有EPoll的锁) 28140609970SGnoCiYeH pub fn do_epoll_ctl( 28240609970SGnoCiYeH epfd: i32, 28340609970SGnoCiYeH op: EPollCtlOption, 28440609970SGnoCiYeH fd: i32, 28540609970SGnoCiYeH epds: &mut EPollEvent, 28640609970SGnoCiYeH nonblock: bool, 28740609970SGnoCiYeH ) -> Result<usize, SystemError> { 28840609970SGnoCiYeH let current_pcb = ProcessManager::current_pcb(); 28940609970SGnoCiYeH let fd_table = current_pcb.fd_table(); 29040609970SGnoCiYeH let fd_table_guard = fd_table.read(); 29140609970SGnoCiYeH 29240609970SGnoCiYeH // 获取epoll和对应fd指向的文件 29340609970SGnoCiYeH let ep_file = fd_table_guard 29440609970SGnoCiYeH .get_file_by_fd(epfd) 29540609970SGnoCiYeH .ok_or(SystemError::EBADF)?; 29640609970SGnoCiYeH let dst_file = fd_table_guard 29740609970SGnoCiYeH .get_file_by_fd(fd) 29840609970SGnoCiYeH .ok_or(SystemError::EBADF)?; 29940609970SGnoCiYeH 30040609970SGnoCiYeH // 检查是否允许 EPOLLWAKEUP 301b5b571e0SLoGin if op != EPollCtlOption::Del { 30240609970SGnoCiYeH epds.events &= !EPollEventType::EPOLLWAKEUP.bits(); 30340609970SGnoCiYeH } 30440609970SGnoCiYeH 30540609970SGnoCiYeH let events = EPollEventType::from_bits_truncate(epds.events); 30640609970SGnoCiYeH 30740609970SGnoCiYeH // 检查获取到的两个文件的正确性 30840609970SGnoCiYeH // 首先是不能自己嵌套自己 30940609970SGnoCiYeH // 然后ep_file必须是epoll文件 31040609970SGnoCiYeH if Arc::ptr_eq(&ep_file, &dst_file) || !Self::is_epoll_file(&ep_file) { 31140609970SGnoCiYeH return Err(SystemError::EINVAL); 31240609970SGnoCiYeH } 31340609970SGnoCiYeH 314b5b571e0SLoGin if op != EPollCtlOption::Del && events.contains(EPollEventType::EPOLLEXCLUSIVE) { 31540609970SGnoCiYeH // epoll独占模式下不允许EpollCtlMod 316b5b571e0SLoGin if op == EPollCtlOption::Mod { 31740609970SGnoCiYeH return Err(SystemError::EINVAL); 31840609970SGnoCiYeH } 31940609970SGnoCiYeH 32040609970SGnoCiYeH // 不支持嵌套的独占唤醒 321b5b571e0SLoGin if op == EPollCtlOption::Add && Self::is_epoll_file(&dst_file) 32240609970SGnoCiYeH || !events 32340609970SGnoCiYeH .difference(EPollEventType::EPOLLEXCLUSIVE_OK_BITS) 32440609970SGnoCiYeH .is_empty() 32540609970SGnoCiYeH { 32640609970SGnoCiYeH return Err(SystemError::EINVAL); 32740609970SGnoCiYeH } 32840609970SGnoCiYeH } 32940609970SGnoCiYeH 33040609970SGnoCiYeH // 从FilePrivateData获取到epoll 331dfe53cf0SGnoCiYeH if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() { 33240609970SGnoCiYeH let mut epoll_guard = { 33340609970SGnoCiYeH if nonblock { 33440609970SGnoCiYeH // 如果设置非阻塞,则尝试获取一次锁 33540609970SGnoCiYeH if let Ok(guard) = epoll_data.epoll.0.try_lock_irqsave() { 33640609970SGnoCiYeH guard 33740609970SGnoCiYeH } else { 33840609970SGnoCiYeH return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 33940609970SGnoCiYeH } 34040609970SGnoCiYeH } else { 34140609970SGnoCiYeH epoll_data.epoll.0.lock_irqsave() 34240609970SGnoCiYeH } 34340609970SGnoCiYeH }; 34440609970SGnoCiYeH 345b5b571e0SLoGin if op == EPollCtlOption::Add { 34640609970SGnoCiYeH // TODO: 循环检查是否为epoll嵌套epoll的情况,如果是则需要检测其深度 34740609970SGnoCiYeH // 这里是需要一种检测算法的,但是目前未考虑epoll嵌套epoll的情况,所以暂时未实现 34840609970SGnoCiYeH // Linux算法:https://code.dragonos.org.cn/xref/linux-6.1.9/fs/eventpoll.c?r=&mo=56953&fi=2057#2133 34940609970SGnoCiYeH if Self::is_epoll_file(&dst_file) { 35040609970SGnoCiYeH todo!(); 35140609970SGnoCiYeH } 35240609970SGnoCiYeH } 35340609970SGnoCiYeH 35440609970SGnoCiYeH let ep_item = epoll_guard.ep_items.get(&fd); 35540609970SGnoCiYeH match op { 356b5b571e0SLoGin EPollCtlOption::Add => { 35740609970SGnoCiYeH // 如果已经存在,则返回错误 35840609970SGnoCiYeH if ep_item.is_some() { 35940609970SGnoCiYeH return Err(SystemError::EEXIST); 36040609970SGnoCiYeH } 36140609970SGnoCiYeH // 设置epoll 36240609970SGnoCiYeH let epitem = Arc::new(EPollItem::new( 36340609970SGnoCiYeH Arc::downgrade(&epoll_data.epoll.0), 36440609970SGnoCiYeH *epds, 36540609970SGnoCiYeH fd, 36640609970SGnoCiYeH Arc::downgrade(&dst_file), 36740609970SGnoCiYeH )); 36840609970SGnoCiYeH Self::ep_insert(&mut epoll_guard, dst_file, epitem)?; 36940609970SGnoCiYeH } 370b5b571e0SLoGin EPollCtlOption::Del => { 37140609970SGnoCiYeH // 不存在则返回错误 37240609970SGnoCiYeH if ep_item.is_none() { 37340609970SGnoCiYeH return Err(SystemError::ENOENT); 37440609970SGnoCiYeH } 37540609970SGnoCiYeH // 删除 37640609970SGnoCiYeH Self::ep_remove(&mut epoll_guard, fd, Some(dst_file))?; 37740609970SGnoCiYeH } 378b5b571e0SLoGin EPollCtlOption::Mod => { 37940609970SGnoCiYeH // 不存在则返回错误 38040609970SGnoCiYeH if ep_item.is_none() { 38140609970SGnoCiYeH return Err(SystemError::ENOENT); 38240609970SGnoCiYeH } 38340609970SGnoCiYeH let ep_item = ep_item.unwrap().clone(); 38440609970SGnoCiYeH if ep_item.event.read().events & EPollEventType::EPOLLEXCLUSIVE.bits() != 0 { 38540609970SGnoCiYeH epds.events |= 38640609970SGnoCiYeH EPollEventType::EPOLLERR.bits() | EPollEventType::EPOLLHUP.bits(); 38740609970SGnoCiYeH 388b5b571e0SLoGin Self::ep_modify(&mut epoll_guard, ep_item, epds)?; 38940609970SGnoCiYeH } 39040609970SGnoCiYeH } 39140609970SGnoCiYeH } 39240609970SGnoCiYeH } 39340609970SGnoCiYeH 39440609970SGnoCiYeH Ok(0) 39540609970SGnoCiYeH } 39640609970SGnoCiYeH 39740609970SGnoCiYeH /// ## epoll_wait的具体实现 39840609970SGnoCiYeH pub fn do_epoll_wait( 39940609970SGnoCiYeH epfd: i32, 40040609970SGnoCiYeH epoll_event: &mut [EPollEvent], 40140609970SGnoCiYeH max_events: i32, 4026fc066acSJomo timespec: Option<PosixTimeSpec>, 40340609970SGnoCiYeH ) -> Result<usize, SystemError> { 40440609970SGnoCiYeH let current_pcb = ProcessManager::current_pcb(); 40540609970SGnoCiYeH let fd_table = current_pcb.fd_table(); 40640609970SGnoCiYeH let fd_table_guard = fd_table.read(); 40740609970SGnoCiYeH 40840609970SGnoCiYeH // 获取epoll文件 40940609970SGnoCiYeH let ep_file = fd_table_guard 41040609970SGnoCiYeH .get_file_by_fd(epfd) 41140609970SGnoCiYeH .ok_or(SystemError::EBADF)?; 41240609970SGnoCiYeH 41340609970SGnoCiYeH drop(fd_table_guard); 41440609970SGnoCiYeH 41540609970SGnoCiYeH // 确保是epoll file 41640609970SGnoCiYeH if !Self::is_epoll_file(&ep_file) { 41740609970SGnoCiYeH return Err(SystemError::EINVAL); 41840609970SGnoCiYeH } 41940609970SGnoCiYeH 42040609970SGnoCiYeH // 从epoll文件获取到epoll 42140609970SGnoCiYeH let mut epolldata = None; 422dfe53cf0SGnoCiYeH if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() { 42340609970SGnoCiYeH epolldata = Some(epoll_data.clone()) 42440609970SGnoCiYeH } 425b5b571e0SLoGin if let Some(epoll_data) = epolldata { 42640609970SGnoCiYeH let epoll = epoll_data.epoll.clone(); 42740609970SGnoCiYeH let epoll_guard = epoll.0.lock_irqsave(); 42840609970SGnoCiYeH 42940609970SGnoCiYeH let mut timeout = false; 430b5b571e0SLoGin if let Some(timespec) = timespec { 43140609970SGnoCiYeH if !(timespec.tv_sec > 0 || timespec.tv_nsec > 0) { 43240609970SGnoCiYeH // 非阻塞情况 43340609970SGnoCiYeH timeout = true; 43440609970SGnoCiYeH } 43540609970SGnoCiYeH } 43640609970SGnoCiYeH // 判断epoll上有没有就绪事件 43740609970SGnoCiYeH let mut available = epoll_guard.ep_events_available(); 438634349e0SLoGin 43940609970SGnoCiYeH drop(epoll_guard); 44040609970SGnoCiYeH loop { 44140609970SGnoCiYeH if available { 44240609970SGnoCiYeH // 如果有就绪的事件,则直接返回就绪事件 44340609970SGnoCiYeH return Self::ep_send_events(epoll.clone(), epoll_event, max_events); 44440609970SGnoCiYeH } 44540609970SGnoCiYeH 44640609970SGnoCiYeH if epoll.0.lock_irqsave().shutdown.load(Ordering::SeqCst) { 44740609970SGnoCiYeH // 如果已经关闭 44840609970SGnoCiYeH return Err(SystemError::EBADF); 44940609970SGnoCiYeH } 45040609970SGnoCiYeH 45140609970SGnoCiYeH // 如果超时 45240609970SGnoCiYeH if timeout { 45340609970SGnoCiYeH return Ok(0); 45440609970SGnoCiYeH } 45540609970SGnoCiYeH 45640609970SGnoCiYeH // 自旋等待一段时间 45740609970SGnoCiYeH available = { 45840609970SGnoCiYeH let mut ret = false; 45940609970SGnoCiYeH for _ in 0..50 { 46040609970SGnoCiYeH if let Ok(guard) = epoll.0.try_lock_irqsave() { 46140609970SGnoCiYeH if guard.ep_events_available() { 46240609970SGnoCiYeH ret = true; 46340609970SGnoCiYeH break; 46440609970SGnoCiYeH } 46540609970SGnoCiYeH } 46640609970SGnoCiYeH } 46740609970SGnoCiYeH // 最后再次不使用try_lock尝试 46840609970SGnoCiYeH if !ret { 46940609970SGnoCiYeH ret = epoll.0.lock_irqsave().ep_events_available(); 47040609970SGnoCiYeH } 47140609970SGnoCiYeH ret 47240609970SGnoCiYeH }; 47340609970SGnoCiYeH 47440609970SGnoCiYeH if available { 47540609970SGnoCiYeH continue; 47640609970SGnoCiYeH } 47740609970SGnoCiYeH 47840609970SGnoCiYeH // 如果有未处理的信号则返回错误 47952bcb59eSGnoCiYeH if current_pcb.sig_info_irqsave().sig_pending().signal().bits() != 0 { 48040609970SGnoCiYeH return Err(SystemError::EINTR); 48140609970SGnoCiYeH } 48240609970SGnoCiYeH 48340609970SGnoCiYeH // 还未等待到事件发生,则睡眠 48440609970SGnoCiYeH // 注册定时器 48540609970SGnoCiYeH let mut timer = None; 486b5b571e0SLoGin if let Some(timespec) = timespec { 48740609970SGnoCiYeH let handle = WakeUpHelper::new(current_pcb.clone()); 48840609970SGnoCiYeH let jiffies = next_n_us_timer_jiffies( 48940609970SGnoCiYeH (timespec.tv_sec * 1000000 + timespec.tv_nsec / 1000) as u64, 49040609970SGnoCiYeH ); 49140609970SGnoCiYeH let inner = Timer::new(handle, jiffies); 49240609970SGnoCiYeH inner.activate(); 49340609970SGnoCiYeH timer = Some(inner); 49440609970SGnoCiYeH } 49540609970SGnoCiYeH let guard = epoll.0.lock_irqsave(); 49640609970SGnoCiYeH unsafe { guard.epoll_wq.sleep_without_schedule() }; 49740609970SGnoCiYeH drop(guard); 498f0c87a89SGnoCiYeH schedule(SchedMode::SM_NONE); 49940609970SGnoCiYeH // 被唤醒后,检查是否有事件可读 50040609970SGnoCiYeH available = epoll.0.lock_irqsave().ep_events_available(); 501b5b571e0SLoGin if let Some(timer) = timer { 502b5b571e0SLoGin if timer.as_ref().timeout() { 50340609970SGnoCiYeH // 超时 50440609970SGnoCiYeH timeout = true; 50540609970SGnoCiYeH } else { 50640609970SGnoCiYeH // 未超时,则取消计时器 507b5b571e0SLoGin timer.cancel(); 50840609970SGnoCiYeH } 50940609970SGnoCiYeH } 51040609970SGnoCiYeH } 51140609970SGnoCiYeH } else { 51240609970SGnoCiYeH panic!("An epoll file does not have the corresponding private information"); 51340609970SGnoCiYeH } 51440609970SGnoCiYeH } 51540609970SGnoCiYeH 51640609970SGnoCiYeH /// ## 将已经准备好的事件拷贝到用户空间 51740609970SGnoCiYeH /// 51840609970SGnoCiYeH /// ### 参数 51940609970SGnoCiYeH /// - epoll: 对应的epoll 52040609970SGnoCiYeH /// - user_event: 用户空间传入的epoll_event地址,因为内存对其问题,所以这里需要直接操作地址 52140609970SGnoCiYeH /// - max_events: 处理的最大事件数量 52240609970SGnoCiYeH fn ep_send_events( 52340609970SGnoCiYeH epoll: LockedEventPoll, 52440609970SGnoCiYeH user_event: &mut [EPollEvent], 52540609970SGnoCiYeH max_events: i32, 52640609970SGnoCiYeH ) -> Result<usize, SystemError> { 52740609970SGnoCiYeH let mut ep_guard = epoll.0.lock_irqsave(); 52840609970SGnoCiYeH let mut res: usize = 0; 52940609970SGnoCiYeH 53040609970SGnoCiYeH // 在水平触发模式下,需要将epitem再次加入队列,在下次循环再次判断是否还有事件 53140609970SGnoCiYeH // (所以边缘触发的效率会高于水平触发,但是水平触发某些情况下能够使得更迅速地向用户反馈) 53240609970SGnoCiYeH let mut push_back = Vec::new(); 53340609970SGnoCiYeH while let Some(epitem) = ep_guard.ready_list.pop_front() { 53440609970SGnoCiYeH if res >= max_events as usize { 53540609970SGnoCiYeH push_back.push(epitem); 53640609970SGnoCiYeH break; 53740609970SGnoCiYeH } 53840609970SGnoCiYeH let ep_events = EPollEventType::from_bits_truncate(epitem.event.read().events); 53940609970SGnoCiYeH 54040609970SGnoCiYeH // 再次poll获取事件(为了防止水平触发一直加入队列) 54140609970SGnoCiYeH let revents = epitem.ep_item_poll(); 54240609970SGnoCiYeH if revents.is_empty() { 54340609970SGnoCiYeH continue; 54440609970SGnoCiYeH } 54540609970SGnoCiYeH 54640609970SGnoCiYeH // 构建触发事件结构体 54740609970SGnoCiYeH let event = EPollEvent { 54840609970SGnoCiYeH events: revents.bits, 54940609970SGnoCiYeH data: epitem.event.read().data, 55040609970SGnoCiYeH }; 55140609970SGnoCiYeH 55240609970SGnoCiYeH // 这里是需要判断下一个写入的位置是否为空指针 55340609970SGnoCiYeH 55440609970SGnoCiYeH // TODO:这里有可能会出现事件丢失的情况 55540609970SGnoCiYeH // 如果用户传入的数组长度小于传入的max_event,到这里时如果已经到数组最大长度,但是未到max_event 55640609970SGnoCiYeH // 会出现的问题是我们会把这个数据写入到后面的内存中,用户无法在传入的数组中拿到事件,而且写脏数据到了后面一片内存,导致事件丢失 55740609970SGnoCiYeH // 出现这个问题的几率比较小,首先是因为用户的使用不规范,后因为前面地址校验是按照max_event来校验的,只会在两块内存连着分配时出现,但是也是需要考虑的 55840609970SGnoCiYeH 55940609970SGnoCiYeH // 以下的写法判断并无意义,只是记一下错误处理 56040609970SGnoCiYeH // offset += core::mem::size_of::<EPollEvent>(); 56140609970SGnoCiYeH // if offset >= max_offset { 56240609970SGnoCiYeH // // 当前指向的地址已为空,则把epitem放回队列 56340609970SGnoCiYeH // ep_guard.ready_list.push_back(epitem.clone()); 56440609970SGnoCiYeH // if res == 0 { 56540609970SGnoCiYeH // // 一个都未写入成功,表明用户传进的地址就是有问题的 56640609970SGnoCiYeH // return Err(SystemError::EFAULT); 56740609970SGnoCiYeH // } 56840609970SGnoCiYeH // } 56940609970SGnoCiYeH 57040609970SGnoCiYeH // 拷贝到用户空间 57140609970SGnoCiYeH user_event[res] = event; 57240609970SGnoCiYeH // 记数加一 57340609970SGnoCiYeH res += 1; 57440609970SGnoCiYeH 5752eab6dd7S曾俊 // crate::debug!("ep send {event:?}"); 57640609970SGnoCiYeH 57740609970SGnoCiYeH if ep_events.contains(EPollEventType::EPOLLONESHOT) { 57840609970SGnoCiYeH let mut event_writer = epitem.event.write(); 57940609970SGnoCiYeH let new_event = event_writer.events & EPollEventType::EP_PRIVATE_BITS.bits; 58040609970SGnoCiYeH event_writer.set_events(new_event); 58140609970SGnoCiYeH } else if !ep_events.contains(EPollEventType::EPOLLET) { 58240609970SGnoCiYeH push_back.push(epitem); 58340609970SGnoCiYeH } 58440609970SGnoCiYeH } 58540609970SGnoCiYeH 58640609970SGnoCiYeH for item in push_back { 58740609970SGnoCiYeH ep_guard.ep_add_ready(item); 58840609970SGnoCiYeH } 58940609970SGnoCiYeH 59040609970SGnoCiYeH Ok(res) 59140609970SGnoCiYeH } 59240609970SGnoCiYeH 59340609970SGnoCiYeH // ### 查看文件是否为epoll文件 594dfe53cf0SGnoCiYeH fn is_epoll_file(file: &Arc<File>) -> bool { 595dfe53cf0SGnoCiYeH if let FilePrivateData::EPoll(_) = *file.private_data.lock() { 59640609970SGnoCiYeH return true; 59740609970SGnoCiYeH } 59840609970SGnoCiYeH return false; 59940609970SGnoCiYeH } 60040609970SGnoCiYeH 60140609970SGnoCiYeH fn ep_insert( 60240609970SGnoCiYeH epoll_guard: &mut SpinLockGuard<EventPoll>, 603dfe53cf0SGnoCiYeH dst_file: Arc<File>, 60440609970SGnoCiYeH epitem: Arc<EPollItem>, 60540609970SGnoCiYeH ) -> Result<(), SystemError> { 60640609970SGnoCiYeH if Self::is_epoll_file(&dst_file) { 60740609970SGnoCiYeH return Err(SystemError::ENOSYS); 60840609970SGnoCiYeH // TODO:现在的实现先不考虑嵌套其它类型的文件(暂时只针对socket),这里的嵌套指epoll/select/poll 60940609970SGnoCiYeH } 61040609970SGnoCiYeH 611dfe53cf0SGnoCiYeH let test_poll = dst_file.poll(); 612b5b571e0SLoGin if test_poll.is_err() && test_poll.unwrap_err() == SystemError::EOPNOTSUPP_OR_ENOTSUP { 61340609970SGnoCiYeH // 如果目标文件不支持poll 61440609970SGnoCiYeH return Err(SystemError::ENOSYS); 61540609970SGnoCiYeH } 61640609970SGnoCiYeH 61740609970SGnoCiYeH epoll_guard.ep_items.insert(epitem.fd, epitem.clone()); 61840609970SGnoCiYeH 61940609970SGnoCiYeH // 检查文件是否已经有事件发生 62040609970SGnoCiYeH let event = epitem.ep_item_poll(); 62140609970SGnoCiYeH if !event.is_empty() { 62240609970SGnoCiYeH // 加入到就绪队列 62340609970SGnoCiYeH epoll_guard.ep_add_ready(epitem.clone()); 62440609970SGnoCiYeH 62540609970SGnoCiYeH epoll_guard.ep_wake_one(); 62640609970SGnoCiYeH } 62740609970SGnoCiYeH 62840609970SGnoCiYeH // TODO: 嵌套epoll? 62940609970SGnoCiYeH 63040609970SGnoCiYeH // 这个标志是用与电源管理相关,暂时不支持 63140609970SGnoCiYeH if epitem.event.read().events & EPollEventType::EPOLLWAKEUP.bits() != 0 { 63240609970SGnoCiYeH return Err(SystemError::ENOSYS); 63340609970SGnoCiYeH } 63440609970SGnoCiYeH 635dfe53cf0SGnoCiYeH dst_file.add_epoll(epitem.clone())?; 63640609970SGnoCiYeH Ok(()) 63740609970SGnoCiYeH } 63840609970SGnoCiYeH 63940609970SGnoCiYeH pub fn ep_remove( 64040609970SGnoCiYeH epoll: &mut SpinLockGuard<EventPoll>, 64140609970SGnoCiYeH fd: i32, 642dfe53cf0SGnoCiYeH dst_file: Option<Arc<File>>, 64340609970SGnoCiYeH ) -> Result<(), SystemError> { 644b5b571e0SLoGin if let Some(dst_file) = dst_file { 645dfe53cf0SGnoCiYeH dst_file.remove_epoll(epoll.self_ref.as_ref().unwrap())?; 64640609970SGnoCiYeH } 64740609970SGnoCiYeH 64840609970SGnoCiYeH let epitem = epoll.ep_items.remove(&fd).unwrap(); 64940609970SGnoCiYeH 65040609970SGnoCiYeH let _ = epoll 65140609970SGnoCiYeH .ready_list 65240609970SGnoCiYeH .extract_if(|item| Arc::ptr_eq(item, &epitem)); 65340609970SGnoCiYeH 65440609970SGnoCiYeH Ok(()) 65540609970SGnoCiYeH } 65640609970SGnoCiYeH 65740609970SGnoCiYeH /// ## 修改已经注册的监听事件 65840609970SGnoCiYeH /// 65940609970SGnoCiYeH /// ### 参数 66040609970SGnoCiYeH /// - epoll_guard: EventPoll的锁 66140609970SGnoCiYeH /// - epitem: 需要修改的描述符对应的epitem 66240609970SGnoCiYeH /// - event: 新的事件 66340609970SGnoCiYeH fn ep_modify( 66440609970SGnoCiYeH epoll_guard: &mut SpinLockGuard<EventPoll>, 66540609970SGnoCiYeH epitem: Arc<EPollItem>, 66640609970SGnoCiYeH event: &EPollEvent, 66740609970SGnoCiYeH ) -> Result<(), SystemError> { 66840609970SGnoCiYeH let mut epi_event_guard = epitem.event.write(); 66940609970SGnoCiYeH 67040609970SGnoCiYeH // 修改epitem 67140609970SGnoCiYeH epi_event_guard.events = event.events; 67240609970SGnoCiYeH epi_event_guard.data = event.data; 67340609970SGnoCiYeH 67440609970SGnoCiYeH drop(epi_event_guard); 67540609970SGnoCiYeH // 修改后检查文件是否已经有感兴趣事件发生 67640609970SGnoCiYeH let event = epitem.ep_item_poll(); 67740609970SGnoCiYeH if !event.is_empty() { 67840609970SGnoCiYeH epoll_guard.ep_add_ready(epitem.clone()); 67940609970SGnoCiYeH 68040609970SGnoCiYeH epoll_guard.ep_wake_one(); 68140609970SGnoCiYeH } 68240609970SGnoCiYeH // TODO:处理EPOLLWAKEUP,目前不支持 68340609970SGnoCiYeH 68440609970SGnoCiYeH Ok(()) 68540609970SGnoCiYeH } 68640609970SGnoCiYeH 68740609970SGnoCiYeH /// ### 判断epoll是否有就绪item 68840609970SGnoCiYeH pub fn ep_events_available(&self) -> bool { 68940609970SGnoCiYeH !self.ready_list.is_empty() 69040609970SGnoCiYeH } 69140609970SGnoCiYeH 69240609970SGnoCiYeH /// ### 将epitem加入到就绪队列,如果为重复添加则忽略 69340609970SGnoCiYeH pub fn ep_add_ready(&mut self, epitem: Arc<EPollItem>) { 69440609970SGnoCiYeH let ret = self.ready_list.iter().find(|epi| Arc::ptr_eq(epi, &epitem)); 69540609970SGnoCiYeH 69640609970SGnoCiYeH if ret.is_none() { 69740609970SGnoCiYeH self.ready_list.push_back(epitem); 69840609970SGnoCiYeH } 69940609970SGnoCiYeH } 70040609970SGnoCiYeH 70140609970SGnoCiYeH /// ### 判断该epoll上是否有进程在等待 70240609970SGnoCiYeH pub fn ep_has_waiter(&self) -> bool { 70340609970SGnoCiYeH self.epoll_wq.len() != 0 70440609970SGnoCiYeH } 70540609970SGnoCiYeH 70640609970SGnoCiYeH /// ### 唤醒所有在epoll上等待的进程 70740609970SGnoCiYeH pub fn ep_wake_all(&self) { 70840609970SGnoCiYeH self.epoll_wq.wakeup_all(None); 70940609970SGnoCiYeH } 71040609970SGnoCiYeH 71140609970SGnoCiYeH /// ### 唤醒所有在epoll上等待的首个进程 71240609970SGnoCiYeH pub fn ep_wake_one(&self) { 71340609970SGnoCiYeH self.epoll_wq.wakeup(None); 71440609970SGnoCiYeH } 7155e948c56SGnoCiYeH 7165e948c56SGnoCiYeH /// ### epoll的回调,支持epoll的文件有事件到来时直接调用该方法即可 7175e948c56SGnoCiYeH pub fn wakeup_epoll( 718840045afSLoGin epitems: &SpinLock<LinkedList<Arc<EPollItem>>>, 7195e948c56SGnoCiYeH pollflags: EPollEventType, 7205e948c56SGnoCiYeH ) -> Result<(), SystemError> { 7215e948c56SGnoCiYeH let mut epitems_guard = epitems.try_lock_irqsave()?; 7225e948c56SGnoCiYeH // 一次只取一个,因为一次也只有一个进程能拿到对应文件的 7235e948c56SGnoCiYeH if let Some(epitem) = epitems_guard.pop_front() { 7245e948c56SGnoCiYeH let epoll = epitem.epoll().upgrade().unwrap(); 7255e948c56SGnoCiYeH let mut epoll_guard = epoll.try_lock()?; 7265e948c56SGnoCiYeH let binding = epitem.clone(); 7275e948c56SGnoCiYeH let event_guard = binding.event().read(); 7285e948c56SGnoCiYeH let ep_events = EPollEventType::from_bits_truncate(event_guard.events()); 7295e948c56SGnoCiYeH 7305e948c56SGnoCiYeH // 检查事件合理性以及是否有感兴趣的事件 7315e948c56SGnoCiYeH if !(ep_events 7325e948c56SGnoCiYeH .difference(EPollEventType::EP_PRIVATE_BITS) 7335e948c56SGnoCiYeH .is_empty() 7345e948c56SGnoCiYeH || pollflags.difference(ep_events).is_empty()) 7355e948c56SGnoCiYeH { 7365e948c56SGnoCiYeH // TODO: 未处理pm相关 7375e948c56SGnoCiYeH 7385e948c56SGnoCiYeH // 首先将就绪的epitem加入等待队列 7395e948c56SGnoCiYeH epoll_guard.ep_add_ready(epitem.clone()); 7405e948c56SGnoCiYeH 7415e948c56SGnoCiYeH if epoll_guard.ep_has_waiter() { 7425e948c56SGnoCiYeH if ep_events.contains(EPollEventType::EPOLLEXCLUSIVE) 7435e948c56SGnoCiYeH && !pollflags.contains(EPollEventType::POLLFREE) 7445e948c56SGnoCiYeH { 7455e948c56SGnoCiYeH // 避免惊群 7465e948c56SGnoCiYeH epoll_guard.ep_wake_one(); 7475e948c56SGnoCiYeH } else { 7485e948c56SGnoCiYeH epoll_guard.ep_wake_all(); 7495e948c56SGnoCiYeH } 7505e948c56SGnoCiYeH } 7515e948c56SGnoCiYeH } 7525e948c56SGnoCiYeH 7535e948c56SGnoCiYeH epitems_guard.push_back(epitem); 7545e948c56SGnoCiYeH } 7555e948c56SGnoCiYeH Ok(()) 7565e948c56SGnoCiYeH } 75740609970SGnoCiYeH } 75840609970SGnoCiYeH 75940609970SGnoCiYeH /// 与C兼容的Epoll事件结构体 76040609970SGnoCiYeH #[derive(Copy, Clone, Default)] 76140609970SGnoCiYeH #[repr(packed)] 762634349e0SLoGin #[repr(C)] 76340609970SGnoCiYeH pub struct EPollEvent { 76440609970SGnoCiYeH /// 表示触发的事件 76540609970SGnoCiYeH events: u32, 76640609970SGnoCiYeH /// 内核态不使用该字段,该字段由用户态自由使用,在事件发生时内核将会原样返回 76740609970SGnoCiYeH data: u64, 76840609970SGnoCiYeH } 76940609970SGnoCiYeH 77040609970SGnoCiYeH impl Debug for EPollEvent { 77140609970SGnoCiYeH fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 77240609970SGnoCiYeH let events = self.events; 77340609970SGnoCiYeH let u64 = self.data; 77440609970SGnoCiYeH f.debug_struct("epoll_event") 77540609970SGnoCiYeH .field("events", &events) 77640609970SGnoCiYeH .field("data", &u64) 77740609970SGnoCiYeH .finish() 77840609970SGnoCiYeH } 77940609970SGnoCiYeH } 78040609970SGnoCiYeH 78140609970SGnoCiYeH impl EPollEvent { 78240609970SGnoCiYeH pub fn set_events(&mut self, events: u32) { 78340609970SGnoCiYeH self.events = events; 78440609970SGnoCiYeH } 78540609970SGnoCiYeH 78640609970SGnoCiYeH pub fn events(&self) -> u32 { 78740609970SGnoCiYeH self.events 78840609970SGnoCiYeH } 78940609970SGnoCiYeH } 79040609970SGnoCiYeH 79140609970SGnoCiYeH /// ## epoll_ctl函数的参数 79240609970SGnoCiYeH #[derive(Debug, PartialEq)] 79340609970SGnoCiYeH pub enum EPollCtlOption { 79440609970SGnoCiYeH /// 注册新的文件描述符到epfd 795b5b571e0SLoGin Add, 79640609970SGnoCiYeH /// 将对应的文件描述符从epfd中删除 797b5b571e0SLoGin Del, 79840609970SGnoCiYeH /// 修改已经注册的文件描述符的监听事件 799b5b571e0SLoGin Mod, 80040609970SGnoCiYeH } 80140609970SGnoCiYeH 80240609970SGnoCiYeH impl EPollCtlOption { 80340609970SGnoCiYeH pub fn from_op_num(op: usize) -> Result<Self, SystemError> { 80440609970SGnoCiYeH match op { 805b5b571e0SLoGin 1 => Ok(Self::Add), 806b5b571e0SLoGin 2 => Ok(Self::Del), 807b5b571e0SLoGin 3 => Ok(Self::Mod), 80840609970SGnoCiYeH _ => Err(SystemError::EINVAL), 80940609970SGnoCiYeH } 81040609970SGnoCiYeH } 81140609970SGnoCiYeH } 81240609970SGnoCiYeH 81340609970SGnoCiYeH bitflags! { 81440609970SGnoCiYeH #[allow(dead_code)] 81540609970SGnoCiYeH pub struct EPollEventType: u32 { 81640609970SGnoCiYeH /// 对应的描述符有新的数据可读时会触发 81740609970SGnoCiYeH const EPOLLIN = 0x00000001; 81840609970SGnoCiYeH /// 对应的描述符有紧急数据可读时会触发 81940609970SGnoCiYeH const EPOLLPRI = 0x00000002; 82040609970SGnoCiYeH /// 对应的描述符可以写入数据时会触发 82140609970SGnoCiYeH const EPOLLOUT = 0x00000004; 82240609970SGnoCiYeH /// 对应的描述符发生错误时会触发 82340609970SGnoCiYeH const EPOLLERR = 0x00000008; 82440609970SGnoCiYeH /// 对应的描述符被挂断(连接关闭)时会触发 82540609970SGnoCiYeH const EPOLLHUP = 0x00000010; 82640609970SGnoCiYeH /// 对应的描述符不是一个有效的文件描述符时会触发 82740609970SGnoCiYeH const EPOLLNVAL = 0x00000020; 82840609970SGnoCiYeH /// 普通数据可读,类似于`EPOLLIN` 82940609970SGnoCiYeH const EPOLLRDNORM = 0x00000040; 83040609970SGnoCiYeH /// 优先级带外数据可读 83140609970SGnoCiYeH const EPOLLRDBAND = 0x00000080; 83240609970SGnoCiYeH /// 普通数据可写,类似于'EPOLLOUT' 83340609970SGnoCiYeH const EPOLLWRNORM = 0x00000100; 83440609970SGnoCiYeH /// 优先级带外数据可写 83540609970SGnoCiYeH const EPOLLWRBAND = 0x00000200; 83640609970SGnoCiYeH /// 通过消息队列收到消息时会触 83740609970SGnoCiYeH const EPOLLMSG = 0x00000400; 83840609970SGnoCiYeH /// 对应的描述符被挂断(连接关闭)的一端发送了 FIN 时会触发(读关闭) 83940609970SGnoCiYeH const EPOLLRDHUP = 0x00002000; 84040609970SGnoCiYeH 84140609970SGnoCiYeH /// 以下为额外选项 84240609970SGnoCiYeH /// 84340609970SGnoCiYeH /// 特定选项,用于异步 I/O,目前未实现 84440609970SGnoCiYeH const EPOLL_URING_WAKE = 1u32 << 27; 84540609970SGnoCiYeH /// 设置epoll为独占模式 84640609970SGnoCiYeH const EPOLLEXCLUSIVE = 1u32 << 28; 84740609970SGnoCiYeH /// 允许在系统挂起时唤醒 epoll,通常用于通过 eventfd 或 timerfd 唤醒 epoll,(通常与电源管理相关,未实现) 84840609970SGnoCiYeH const EPOLLWAKEUP = 1u32 << 29; 84940609970SGnoCiYeH /// 表示只监听一次事件,之后需要重新添加 85040609970SGnoCiYeH const EPOLLONESHOT = 1u32 << 30; 85140609970SGnoCiYeH 85240609970SGnoCiYeH /// 启用边缘触发模式(即只有下次触发事件时才会通过epoll_wait返回), 85340609970SGnoCiYeH /// 对应为水平触发(默认),水平触发模式下若这次未处理完数据,那epoll还会将其加入自己的就绪队列 85440609970SGnoCiYeH const EPOLLET = 1u32 << 31; 85540609970SGnoCiYeH 85640609970SGnoCiYeH /// 以下为组合码 85740609970SGnoCiYeH const EPOLLINOUT_BITS = Self::EPOLLIN.bits | Self::EPOLLOUT.bits; 85840609970SGnoCiYeH const EPOLLEXCLUSIVE_OK_BITS = 85940609970SGnoCiYeH Self::EPOLLINOUT_BITS.bits 86040609970SGnoCiYeH | Self::EPOLLERR.bits 86140609970SGnoCiYeH | Self::EPOLLHUP.bits 86240609970SGnoCiYeH | Self::EPOLLWAKEUP.bits 86340609970SGnoCiYeH | Self::EPOLLET.bits 86440609970SGnoCiYeH | Self::EPOLLEXCLUSIVE.bits; 86540609970SGnoCiYeH 86640609970SGnoCiYeH const EP_PRIVATE_BITS = 86740609970SGnoCiYeH Self::EPOLLWAKEUP.bits 86840609970SGnoCiYeH | Self::EPOLLONESHOT.bits 86940609970SGnoCiYeH | Self::EPOLLET.bits 87040609970SGnoCiYeH | Self::EPOLLEXCLUSIVE.bits; 87140609970SGnoCiYeH 87240609970SGnoCiYeH /// 表示epoll已经被释放,但是在目前的设计中未用到 87340609970SGnoCiYeH const POLLFREE = 0x4000; 874634349e0SLoGin 875634349e0SLoGin /// listen状态的socket可以接受连接 876634349e0SLoGin const EPOLL_LISTEN_CAN_ACCEPT = Self::EPOLLIN.bits | Self::EPOLLRDNORM.bits; 87740609970SGnoCiYeH } 87840609970SGnoCiYeH } 879