event_poll.rs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. use core::{
  2. fmt::Debug,
  3. sync::atomic::{AtomicBool, Ordering},
  4. };
  5. use crate::{
  6. filesystem::vfs::{
  7. file::{File, FileMode},
  8. FilePrivateData,
  9. },
  10. libs::{
  11. rbtree::RBTree,
  12. spinlock::{SpinLock, SpinLockGuard},
  13. wait_queue::WaitQueue,
  14. },
  15. process::ProcessManager,
  16. sched::{schedule, SchedMode},
  17. time::{
  18. timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
  19. PosixTimeSpec,
  20. },
  21. };
  22. use alloc::{
  23. collections::LinkedList,
  24. sync::{Arc, Weak},
  25. vec::Vec,
  26. };
  27. use system_error::SystemError;
  28. use super::{fs::EPollInode, EPollCtlOption, EPollEvent, EPollEventType, EPollItem};
  29. /// 内核的Epoll对象结构体,当用户创建一个Epoll时,内核就会创建一个该类型对象
  30. /// 它对应一个epfd
  31. #[derive(Debug)]
  32. pub struct EventPoll {
  33. /// epoll_wait用到的等待队列
  34. epoll_wq: WaitQueue,
  35. /// 维护所有添加进来的socket的红黑树
  36. ep_items: RBTree<i32, Arc<EPollItem>>,
  37. /// 接收就绪的描述符列表
  38. ready_list: LinkedList<Arc<EPollItem>>,
  39. /// 是否已经关闭
  40. shutdown: AtomicBool,
  41. self_ref: Option<Weak<SpinLock<EventPoll>>>,
  42. }
  43. impl EventPoll {
  44. pub const EP_MAX_EVENTS: u32 = u32::MAX / (core::mem::size_of::<EPollEvent>() as u32);
  45. /// 用于获取inode中的epitem队列
  46. pub const ADD_EPOLLITEM: u32 = 0x7965;
  47. fn new() -> Self {
  48. Self {
  49. epoll_wq: WaitQueue::default(),
  50. ep_items: RBTree::new(),
  51. ready_list: LinkedList::new(),
  52. shutdown: AtomicBool::new(false),
  53. self_ref: None,
  54. }
  55. }
  56. /// 关闭epoll时,执行的逻辑
  57. pub(super) fn close(&mut self) -> Result<(), SystemError> {
  58. // 唤醒epoll上面等待的所有进程
  59. self.shutdown.store(true, Ordering::SeqCst);
  60. self.ep_wake_all();
  61. let fds: Vec<i32> = self.ep_items.keys().cloned().collect::<Vec<_>>();
  62. // 清理红黑树里面的epitems
  63. for fd in fds {
  64. let fdtable = ProcessManager::current_pcb().basic().try_fd_table().clone();
  65. let file = fdtable.and_then(|fdtable| fdtable.read().get_file_by_fd(fd));
  66. if let Some(file) = file {
  67. let epitm = self.ep_items.get(&fd).unwrap();
  68. file.remove_epitem(epitm)?;
  69. }
  70. self.ep_items.remove(&fd);
  71. }
  72. Ok(())
  73. }
  74. /// ## 创建epoll对象, 并将其加入到当前进程的fd_table中
  75. ///
  76. /// ### 参数
  77. /// - flags: 创建的epoll文件的FileMode
  78. ///
  79. /// ### 返回值
  80. /// - 成功则返回Ok(fd),否则返回Err
  81. pub fn create_epoll(flags: FileMode) -> Result<usize, SystemError> {
  82. let ep_file = Self::create_epoll_file(flags)?;
  83. let current_pcb = ProcessManager::current_pcb();
  84. let fd_table = current_pcb.fd_table();
  85. let mut fd_table_guard = fd_table.write();
  86. let fd = fd_table_guard.alloc_fd(ep_file, None)?;
  87. Ok(fd as usize)
  88. }
  89. /// ## 创建epoll文件
  90. pub fn create_epoll_file(flags: FileMode) -> Result<File, SystemError> {
  91. if !flags.difference(FileMode::O_CLOEXEC).is_empty() {
  92. return Err(SystemError::EINVAL);
  93. }
  94. // 创建epoll
  95. let epoll = Self::do_create_epoll();
  96. // 创建epoll的inode对象
  97. let epoll_inode = EPollInode::new(epoll.clone());
  98. let mut ep_file = File::new(
  99. epoll_inode,
  100. FileMode::O_RDWR | (flags & FileMode::O_CLOEXEC),
  101. )?;
  102. // 设置ep_file的FilePrivateData
  103. ep_file.private_data = SpinLock::new(FilePrivateData::EPoll(EPollPrivateData { epoll }));
  104. Ok(ep_file)
  105. }
  106. fn do_create_epoll() -> LockedEventPoll {
  107. let epoll = LockedEventPoll(Arc::new(SpinLock::new(EventPoll::new())));
  108. epoll.0.lock().self_ref = Some(Arc::downgrade(&epoll.0));
  109. epoll
  110. }
  111. /// ## epoll_ctl的具体实现
  112. ///
  113. /// 根据不同的op对epoll文件进行增删改
  114. ///
  115. /// ### 参数
  116. /// - ep_file: epoll文件
  117. /// - op: 对应的操作
  118. /// - dstfd: 操作对应的文件描述符
  119. /// - dst_file: 操作对应的文件(与dstfd对应)
  120. /// - epds: 从用户态传入的event,若op为EpollCtlAdd,则对应注册的监听事件,若op为EPollCtlMod,则对应更新的事件,删除操作不涉及此字段
  121. /// - nonblock: 定义这次操作是否为非阻塞(有可能其他地方占有EPoll的锁)
  122. fn do_epoll_ctl(
  123. ep_file: Arc<File>,
  124. op: EPollCtlOption,
  125. dstfd: i32,
  126. dst_file: Arc<File>,
  127. mut epds: EPollEvent,
  128. nonblock: bool,
  129. ) -> Result<usize, SystemError> {
  130. // 检查是否允许 EPOLLWAKEUP
  131. if op != EPollCtlOption::Del {
  132. epds.events &= !EPollEventType::EPOLLWAKEUP.bits();
  133. }
  134. let events = EPollEventType::from_bits_truncate(epds.events);
  135. // 检查获取到的两个文件的正确性
  136. // 首先是不能自己嵌套自己
  137. // 然后ep_file必须是epoll文件
  138. if Arc::ptr_eq(&ep_file, &dst_file) || !Self::is_epoll_file(&ep_file) {
  139. return Err(SystemError::EINVAL);
  140. }
  141. if op != EPollCtlOption::Del && events.contains(EPollEventType::EPOLLEXCLUSIVE) {
  142. // epoll独占模式下不允许EpollCtlMod
  143. if op == EPollCtlOption::Mod {
  144. return Err(SystemError::EINVAL);
  145. }
  146. // 不支持嵌套的独占唤醒
  147. if op == EPollCtlOption::Add && Self::is_epoll_file(&dst_file)
  148. || !events
  149. .difference(EPollEventType::EPOLLEXCLUSIVE_OK_BITS)
  150. .is_empty()
  151. {
  152. return Err(SystemError::EINVAL);
  153. }
  154. }
  155. // 从FilePrivateData获取到epoll
  156. if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() {
  157. let mut epoll_guard = {
  158. if nonblock {
  159. // 如果设置非阻塞,则尝试获取一次锁
  160. if let Ok(guard) = epoll_data.epoll.0.try_lock_irqsave() {
  161. guard
  162. } else {
  163. return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
  164. }
  165. } else {
  166. epoll_data.epoll.0.lock_irqsave()
  167. }
  168. };
  169. if op == EPollCtlOption::Add {
  170. // TODO: 循环检查是否为epoll嵌套epoll的情况,如果是则需要检测其深度
  171. // 这里是需要一种检测算法的,但是目前未考虑epoll嵌套epoll的情况,所以暂时未实现
  172. // Linux算法:https://code.dragonos.org.cn/xref/linux-6.1.9/fs/eventpoll.c?r=&mo=56953&fi=2057#2133
  173. if Self::is_epoll_file(&dst_file) {
  174. todo!();
  175. }
  176. }
  177. let ep_item = epoll_guard.ep_items.get(&dstfd).cloned();
  178. match op {
  179. EPollCtlOption::Add => {
  180. // 如果已经存在,则返回错误
  181. if ep_item.is_some() {
  182. return Err(SystemError::EEXIST);
  183. }
  184. // 设置epoll
  185. let epitem = Arc::new(EPollItem::new(
  186. Arc::downgrade(&epoll_data.epoll.0),
  187. epds,
  188. dstfd,
  189. Arc::downgrade(&dst_file),
  190. ));
  191. Self::ep_insert(&mut epoll_guard, dst_file, epitem)?;
  192. }
  193. EPollCtlOption::Del => {
  194. match ep_item {
  195. Some(ref ep_item) => {
  196. // 删除
  197. Self::ep_remove(&mut epoll_guard, dstfd, Some(dst_file), ep_item)?;
  198. }
  199. None => {
  200. // 不存在则返回错误
  201. return Err(SystemError::ENOENT);
  202. }
  203. }
  204. }
  205. EPollCtlOption::Mod => {
  206. // 不存在则返回错误
  207. if ep_item.is_none() {
  208. return Err(SystemError::ENOENT);
  209. }
  210. let ep_item = ep_item.unwrap().clone();
  211. if ep_item.event.read().events & EPollEventType::EPOLLEXCLUSIVE.bits() != 0 {
  212. epds.events |=
  213. EPollEventType::EPOLLERR.bits() | EPollEventType::EPOLLHUP.bits();
  214. Self::ep_modify(&mut epoll_guard, ep_item, &epds)?;
  215. }
  216. }
  217. }
  218. }
  219. Ok(0)
  220. }
  221. pub fn epoll_ctl_with_epfd(
  222. epfd: i32,
  223. op: EPollCtlOption,
  224. dstfd: i32,
  225. epds: EPollEvent,
  226. nonblock: bool,
  227. ) -> Result<usize, SystemError> {
  228. let current_pcb = ProcessManager::current_pcb();
  229. let fd_table = current_pcb.fd_table();
  230. let fd_table_guard = fd_table.read();
  231. // 获取epoll和对应fd指向的文件
  232. let ep_file = fd_table_guard
  233. .get_file_by_fd(epfd)
  234. .ok_or(SystemError::EBADF)?;
  235. let dst_file = fd_table_guard
  236. .get_file_by_fd(dstfd)
  237. .ok_or(SystemError::EBADF)?;
  238. drop(fd_table_guard);
  239. Self::do_epoll_ctl(ep_file, op, dstfd, dst_file, epds, nonblock)
  240. }
  241. pub fn epoll_ctl_with_epfile(
  242. ep_file: Arc<File>,
  243. op: EPollCtlOption,
  244. dstfd: i32,
  245. epds: EPollEvent,
  246. nonblock: bool,
  247. ) -> Result<usize, SystemError> {
  248. let current_pcb = ProcessManager::current_pcb();
  249. let fd_table = current_pcb.fd_table();
  250. let fd_table_guard = fd_table.read();
  251. let dst_file = fd_table_guard
  252. .get_file_by_fd(dstfd)
  253. .ok_or(SystemError::EBADF)?;
  254. drop(fd_table_guard);
  255. Self::do_epoll_ctl(ep_file, op, dstfd, dst_file, epds, nonblock)
  256. }
  257. pub fn epoll_wait(
  258. epfd: i32,
  259. epoll_event: &mut [EPollEvent],
  260. max_events: i32,
  261. timespec: Option<PosixTimeSpec>,
  262. ) -> Result<usize, SystemError> {
  263. let current_pcb = ProcessManager::current_pcb();
  264. let fd_table = current_pcb.fd_table();
  265. let fd_table_guard = fd_table.read();
  266. // 获取epoll文件
  267. let ep_file = fd_table_guard
  268. .get_file_by_fd(epfd)
  269. .ok_or(SystemError::EBADF)?;
  270. drop(fd_table_guard);
  271. Self::epoll_wait_with_file(ep_file, epoll_event, max_events, timespec)
  272. }
  273. /// ## epoll_wait的具体实现
  274. pub fn epoll_wait_with_file(
  275. ep_file: Arc<File>,
  276. epoll_event: &mut [EPollEvent],
  277. max_events: i32,
  278. timespec: Option<PosixTimeSpec>,
  279. ) -> Result<usize, SystemError> {
  280. let current_pcb = ProcessManager::current_pcb();
  281. // 确保是epoll file
  282. if !Self::is_epoll_file(&ep_file) {
  283. return Err(SystemError::EINVAL);
  284. }
  285. // 从epoll文件获取到epoll
  286. let mut epolldata = None;
  287. if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() {
  288. epolldata = Some(epoll_data.clone())
  289. }
  290. if let Some(epoll_data) = epolldata {
  291. let epoll = epoll_data.epoll.clone();
  292. let epoll_guard = epoll.0.lock_irqsave();
  293. let mut timeout = false;
  294. if let Some(timespec) = timespec {
  295. if !(timespec.tv_sec > 0 || timespec.tv_nsec > 0) {
  296. // 非阻塞情况
  297. timeout = true;
  298. }
  299. } else if timespec.is_none() {
  300. // 非阻塞情况
  301. timeout = false;
  302. }
  303. // 判断epoll上有没有就绪事件
  304. let mut available = epoll_guard.ep_events_available();
  305. drop(epoll_guard);
  306. loop {
  307. if available {
  308. // 如果有就绪的事件,则直接返回就绪事件
  309. return Self::ep_send_events(epoll.clone(), epoll_event, max_events);
  310. }
  311. if epoll.0.lock_irqsave().shutdown.load(Ordering::SeqCst) {
  312. // 如果已经关闭
  313. return Err(SystemError::EBADF);
  314. }
  315. // 如果超时
  316. if timeout {
  317. return Ok(0);
  318. }
  319. // 自旋等待一段时间
  320. available = {
  321. let mut ret = false;
  322. for _ in 0..50 {
  323. if let Ok(guard) = epoll.0.try_lock_irqsave() {
  324. if guard.ep_events_available() {
  325. ret = true;
  326. break;
  327. }
  328. }
  329. }
  330. // 最后再次不使用try_lock尝试
  331. if !ret {
  332. ret = epoll.0.lock_irqsave().ep_events_available();
  333. }
  334. ret
  335. };
  336. if available {
  337. continue;
  338. }
  339. // 如果有未处理且未被屏蔽的信号则返回错误
  340. if current_pcb.has_pending_signal_fast()
  341. && current_pcb.has_pending_not_masked_signal()
  342. {
  343. return Err(SystemError::ERESTARTSYS);
  344. }
  345. // 还未等待到事件发生,则睡眠
  346. // 注册定时器
  347. let mut timer = None;
  348. if let Some(timespec) = timespec {
  349. let handle = WakeUpHelper::new(current_pcb.clone());
  350. let jiffies = next_n_us_timer_jiffies(
  351. (timespec.tv_sec * 1000000 + timespec.tv_nsec / 1000) as u64,
  352. );
  353. let inner: Arc<Timer> = Timer::new(handle, jiffies);
  354. inner.activate();
  355. timer = Some(inner);
  356. }
  357. let guard = epoll.0.lock_irqsave();
  358. // 睡眠,等待事件发生
  359. // 如果wq已经dead,则直接返回错误
  360. unsafe { guard.epoll_wq.sleep_without_schedule() }.inspect_err(|_| {
  361. if let Some(timer) = timer.as_ref() {
  362. timer.cancel();
  363. }
  364. })?;
  365. drop(guard);
  366. schedule(SchedMode::SM_NONE);
  367. // 被唤醒后,检查是否有事件可读
  368. available = epoll.0.lock_irqsave().ep_events_available();
  369. if let Some(timer) = timer {
  370. if timer.as_ref().timeout() {
  371. // 超时
  372. timeout = true;
  373. } else {
  374. // 未超时,则取消计时器
  375. timer.cancel();
  376. }
  377. }
  378. }
  379. } else {
  380. panic!("An epoll file does not have the corresponding private information");
  381. }
  382. }
  383. /// ## 将已经准备好的事件拷贝到用户空间
  384. ///
  385. /// ### 参数
  386. /// - epoll: 对应的epoll
  387. /// - user_event: 用户空间传入的epoll_event地址,因为内存对其问题,所以这里需要直接操作地址
  388. /// - max_events: 处理的最大事件数量
  389. fn ep_send_events(
  390. epoll: LockedEventPoll,
  391. user_event: &mut [EPollEvent],
  392. max_events: i32,
  393. ) -> Result<usize, SystemError> {
  394. if user_event.len() < max_events as usize {
  395. return Err(SystemError::EINVAL);
  396. }
  397. let mut ep_guard = epoll.0.lock_irqsave();
  398. let mut res: usize = 0;
  399. // 在水平触发模式下,需要将epitem再次加入队列,在下次循环再次判断是否还有事件
  400. // (所以边缘触发的效率会高于水平触发,但是水平触发某些情况下能够使得更迅速地向用户反馈)
  401. let mut push_back = Vec::new();
  402. while let Some(epitem) = ep_guard.ready_list.pop_front() {
  403. if res >= max_events as usize {
  404. push_back.push(epitem);
  405. break;
  406. }
  407. let ep_events = EPollEventType::from_bits_truncate(epitem.event.read().events);
  408. // 再次poll获取事件(为了防止水平触发一直加入队列)
  409. let revents = epitem.ep_item_poll();
  410. if revents.is_empty() {
  411. continue;
  412. }
  413. // 构建触发事件结构体
  414. let event = EPollEvent {
  415. events: revents.bits,
  416. data: epitem.event.read().data,
  417. };
  418. // 这里是需要判断下一个写入的位置是否为空指针
  419. // TODO:这里有可能会出现事件丢失的情况
  420. // 如果用户传入的数组长度小于传入的max_event,到这里时如果已经到数组最大长度,但是未到max_event
  421. // 会出现的问题是我们会把这个数据写入到后面的内存中,用户无法在传入的数组中拿到事件,而且写脏数据到了后面一片内存,导致事件丢失
  422. // 出现这个问题的几率比较小,首先是因为用户的使用不规范,后因为前面地址校验是按照max_event来校验的,只会在两块内存连着分配时出现,但是也是需要考虑的
  423. // 以下的写法判断并无意义,只是记一下错误处理
  424. // offset += core::mem::size_of::<EPollEvent>();
  425. // if offset >= max_offset {
  426. // // 当前指向的地址已为空,则把epitem放回队列
  427. // ep_guard.ready_list.push_back(epitem.clone());
  428. // if res == 0 {
  429. // // 一个都未写入成功,表明用户传进的地址就是有问题的
  430. // return Err(SystemError::EFAULT);
  431. // }
  432. // }
  433. // 拷贝到用户空间
  434. user_event[res] = event;
  435. // 记数加一
  436. res += 1;
  437. // crate::debug!("ep send {event:?}");
  438. if ep_events.contains(EPollEventType::EPOLLONESHOT) {
  439. let mut event_writer = epitem.event.write();
  440. let new_event = event_writer.events & EPollEventType::EP_PRIVATE_BITS.bits;
  441. event_writer.set_events(new_event);
  442. } else if !ep_events.contains(EPollEventType::EPOLLET) {
  443. push_back.push(epitem);
  444. }
  445. }
  446. for item in push_back {
  447. ep_guard.ep_add_ready(item);
  448. }
  449. Ok(res)
  450. }
  451. // ### 查看文件是否为epoll文件
  452. fn is_epoll_file(file: &Arc<File>) -> bool {
  453. if let FilePrivateData::EPoll(_) = *file.private_data.lock() {
  454. return true;
  455. }
  456. return false;
  457. }
  458. fn ep_insert(
  459. epoll_guard: &mut SpinLockGuard<EventPoll>,
  460. dst_file: Arc<File>,
  461. epitem: Arc<EPollItem>,
  462. ) -> Result<(), SystemError> {
  463. if Self::is_epoll_file(&dst_file) {
  464. return Err(SystemError::ENOSYS);
  465. // TODO:现在的实现先不考虑嵌套其它类型的文件(暂时只针对socket),这里的嵌套指epoll/select/poll
  466. }
  467. let test_poll = dst_file.poll();
  468. if test_poll.is_err() && test_poll.unwrap_err() == SystemError::EOPNOTSUPP_OR_ENOTSUP {
  469. // 如果目标文件不支持poll
  470. return Err(SystemError::ENOSYS);
  471. }
  472. epoll_guard.ep_items.insert(epitem.fd, epitem.clone());
  473. // 检查文件是否已经有事件发生
  474. let event = epitem.ep_item_poll();
  475. if !event.is_empty() {
  476. // 加入到就绪队列
  477. epoll_guard.ep_add_ready(epitem.clone());
  478. epoll_guard.ep_wake_one();
  479. }
  480. // TODO: 嵌套epoll?
  481. // 这个标志是用与电源管理相关,暂时不支持
  482. if epitem.event.read().events & EPollEventType::EPOLLWAKEUP.bits() != 0 {
  483. return Err(SystemError::ENOSYS);
  484. }
  485. dst_file.add_epitem(epitem.clone())?;
  486. Ok(())
  487. }
  488. pub fn ep_remove(
  489. epoll: &mut SpinLockGuard<EventPoll>,
  490. fd: i32,
  491. dst_file: Option<Arc<File>>,
  492. epitem: &Arc<EPollItem>,
  493. ) -> Result<(), SystemError> {
  494. if let Some(dst_file) = dst_file {
  495. dst_file.remove_epitem(epitem)?;
  496. }
  497. if let Some(epitem) = epoll.ep_items.remove(&fd) {
  498. epoll.ready_list.retain(|item| !Arc::ptr_eq(item, &epitem));
  499. }
  500. Ok(())
  501. }
  502. /// ## 修改已经注册的监听事件
  503. ///
  504. /// ### 参数
  505. /// - epoll_guard: EventPoll的锁
  506. /// - epitem: 需要修改的描述符对应的epitem
  507. /// - event: 新的事件
  508. fn ep_modify(
  509. epoll_guard: &mut SpinLockGuard<EventPoll>,
  510. epitem: Arc<EPollItem>,
  511. event: &EPollEvent,
  512. ) -> Result<(), SystemError> {
  513. let mut epi_event_guard = epitem.event.write();
  514. // 修改epitem
  515. epi_event_guard.events = event.events;
  516. epi_event_guard.data = event.data;
  517. drop(epi_event_guard);
  518. // 修改后检查文件是否已经有感兴趣事件发生
  519. let event = epitem.ep_item_poll();
  520. if !event.is_empty() {
  521. epoll_guard.ep_add_ready(epitem.clone());
  522. epoll_guard.ep_wake_one();
  523. }
  524. // TODO:处理EPOLLWAKEUP,目前不支持
  525. Ok(())
  526. }
  527. /// ### 判断epoll是否有就绪item
  528. pub fn ep_events_available(&self) -> bool {
  529. !self.ready_list.is_empty()
  530. }
  531. /// ### 将epitem加入到就绪队列,如果为重复添加则忽略
  532. pub fn ep_add_ready(&mut self, epitem: Arc<EPollItem>) {
  533. let ret = self.ready_list.iter().find(|epi| Arc::ptr_eq(epi, &epitem));
  534. if ret.is_none() {
  535. self.ready_list.push_back(epitem);
  536. }
  537. }
  538. /// ### 判断该epoll上是否有进程在等待
  539. pub fn ep_has_waiter(&self) -> bool {
  540. self.epoll_wq.len() != 0
  541. }
  542. /// ### 唤醒所有在epoll上等待的进程
  543. pub fn ep_wake_all(&self) {
  544. self.epoll_wq.wakeup_all(None);
  545. }
  546. /// ### 唤醒所有在epoll上等待的首个进程
  547. pub fn ep_wake_one(&self) {
  548. self.epoll_wq.wakeup(None);
  549. }
  550. /// ### epoll的回调,支持epoll的文件有事件到来时直接调用该方法即可
  551. pub fn wakeup_epoll(
  552. epitems: &SpinLock<LinkedList<Arc<EPollItem>>>,
  553. pollflags: EPollEventType,
  554. ) -> Result<(), SystemError> {
  555. let epitems_guard = epitems.try_lock_irqsave()?;
  556. for epitem in epitems_guard.iter() {
  557. // The upgrade is safe because EventPoll always exists when the epitem is in the list
  558. let epoll = epitem.epoll().upgrade();
  559. if epoll.is_none() {
  560. // 如果epoll已经被释放,则直接跳过
  561. continue;
  562. }
  563. let epoll = epoll.unwrap();
  564. let mut epoll_guard = epoll.try_lock()?;
  565. let binding = epitem.clone();
  566. let event_guard = binding.event().read();
  567. let ep_events = EPollEventType::from_bits_truncate(event_guard.events());
  568. // 检查事件合理性以及是否有感兴趣的事件
  569. if !(ep_events
  570. .difference(EPollEventType::EP_PRIVATE_BITS)
  571. .is_empty()
  572. || pollflags.difference(ep_events).is_empty())
  573. {
  574. // TODO: 未处理pm相关
  575. // 首先将就绪的epitem加入等待队列
  576. epoll_guard.ep_add_ready(epitem.clone());
  577. if epoll_guard.ep_has_waiter() {
  578. if ep_events.contains(EPollEventType::EPOLLEXCLUSIVE)
  579. && !pollflags.contains(EPollEventType::POLLFREE)
  580. {
  581. // 避免惊群
  582. epoll_guard.ep_wake_one();
  583. } else {
  584. epoll_guard.ep_wake_all();
  585. }
  586. }
  587. }
  588. }
  589. Ok(())
  590. }
  591. }
  592. #[derive(Debug, Clone)]
  593. pub struct LockedEventPoll(pub(super) Arc<SpinLock<EventPoll>>);
  594. /// ### Epoll文件的私有信息
  595. #[derive(Debug, Clone)]
  596. pub struct EPollPrivateData {
  597. pub(super) epoll: LockedEventPoll,
  598. }