mod.rs 31 KB

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