mod.rs 29 KB

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