epoll.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. use super::{
  2. super::{types::*, Pal, PalEpoll},
  3. Sys,
  4. };
  5. use crate::{
  6. fs::File,
  7. header::{errno::*, fcntl::*, signal::sigset_t, sys_epoll::*},
  8. io::prelude::*,
  9. platform,
  10. };
  11. use core::{mem, slice};
  12. use syscall::{
  13. data::{Event, TimeSpec},
  14. flag::EVENT_READ,
  15. };
  16. impl PalEpoll for Sys {
  17. fn epoll_create1(flags: c_int) -> c_int {
  18. Sys::open(c_str!("event:"), O_RDWR | flags, 0)
  19. }
  20. fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int {
  21. match op {
  22. EPOLL_CTL_ADD | EPOLL_CTL_MOD => {
  23. Sys::write(
  24. epfd,
  25. &Event {
  26. id: fd as usize,
  27. flags: syscall::EventFlags::from_bits(unsafe { (*event).events as usize })
  28. .expect("epoll: invalid bit pattern"),
  29. // NOTE: Danger when using something smaller than 64-bit
  30. // systems. If this is needed, use a box or something
  31. data: unsafe { (*event).data.u64 as usize },
  32. },
  33. ) as c_int
  34. }
  35. EPOLL_CTL_DEL => {
  36. Sys::write(
  37. epfd,
  38. &Event {
  39. id: fd as usize,
  40. flags: syscall::EventFlags::empty(),
  41. //TODO: Is data required?
  42. data: 0,
  43. },
  44. ) as c_int
  45. }
  46. _ => {
  47. unsafe { platform::errno = EINVAL };
  48. return -1;
  49. }
  50. }
  51. }
  52. fn epoll_pwait(
  53. epfd: c_int,
  54. events: *mut epoll_event,
  55. maxevents: c_int,
  56. timeout: c_int,
  57. _sigset: *const sigset_t,
  58. ) -> c_int {
  59. // TODO: sigset
  60. assert_eq!(mem::size_of::<epoll_event>(), mem::size_of::<Event>());
  61. let timer_opt = if timeout != -1 {
  62. match File::open(c_str!("time:4"), O_RDWR) {
  63. Err(_) => return -1,
  64. Ok(mut timer) => {
  65. if Sys::write(
  66. epfd,
  67. &Event {
  68. id: timer.fd as usize,
  69. flags: EVENT_READ,
  70. data: 0,
  71. },
  72. ) == -1
  73. {
  74. return -1;
  75. }
  76. let mut time = TimeSpec::default();
  77. if let Err(err) = timer.read(&mut time) {
  78. return -1;
  79. }
  80. time.tv_sec += (timeout as i64) / 1000;
  81. time.tv_nsec += (timeout % 1000) * 1000000;
  82. if let Err(err) = timer.write(&time) {
  83. return -1;
  84. }
  85. Some(timer)
  86. }
  87. }
  88. } else {
  89. None
  90. };
  91. let bytes_read = Sys::read(epfd, unsafe {
  92. slice::from_raw_parts_mut(events as *mut u8, maxevents as usize)
  93. });
  94. if bytes_read == -1 {
  95. return -1;
  96. }
  97. let read = bytes_read as usize / mem::size_of::<syscall::Event>();
  98. let mut count = 0;
  99. for i in 0..read {
  100. unsafe {
  101. let event_ptr = events.add(i);
  102. let event = *(event_ptr as *mut Event);
  103. if let Some(ref timer) = timer_opt {
  104. if event.id as c_int == timer.fd {
  105. // Do not count timer event
  106. continue;
  107. }
  108. }
  109. *event_ptr = epoll_event {
  110. events: event.flags.bits() as _,
  111. data: epoll_data {
  112. u64: event.data as u64,
  113. },
  114. ..Default::default()
  115. };
  116. count += 1;
  117. }
  118. }
  119. count as c_int
  120. }
  121. }