1use std::mem;
6use std::ptr;
7use std::time::Duration;
8
9use libc::c_void;
10use libc::eventfd;
11use libc::read;
12use libc::write;
13use libc::POLLIN;
14use serde::Deserialize;
15use serde::Serialize;
16
17use super::errno_result;
18use super::Error;
19use super::RawDescriptor;
20use super::Result;
21use crate::descriptor::AsRawDescriptor;
22use crate::descriptor::FromRawDescriptor;
23use crate::descriptor::IntoRawDescriptor;
24use crate::descriptor::SafeDescriptor;
25use crate::handle_eintr_errno;
26use crate::unix::duration_to_timespec;
27use crate::EventWaitResult;
28
29#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
34#[serde(transparent)]
35pub(crate) struct PlatformEvent {
36 event_handle: SafeDescriptor,
37}
38
39pub trait EventExt {
41 fn write_count(&self, v: u64) -> Result<()>;
43 fn read_count(&self) -> Result<u64>;
45}
46
47impl EventExt for crate::Event {
48 fn write_count(&self, v: u64) -> Result<()> {
49 self.0.write_count(v)
50 }
51
52 fn read_count(&self) -> Result<u64> {
53 self.0.read_count()
54 }
55}
56
57impl PlatformEvent {
58 pub fn new() -> Result<PlatformEvent> {
60 let ret = unsafe { eventfd(0, 0) };
64 if ret < 0 {
65 return errno_result();
66 }
67 Ok(PlatformEvent {
68 event_handle: unsafe { SafeDescriptor::from_raw_descriptor(ret) },
72 })
73 }
74
75 pub fn write_count(&self, v: u64) -> Result<()> {
77 let ret = handle_eintr_errno!(unsafe {
81 write(
82 self.as_raw_descriptor(),
83 &v as *const u64 as *const c_void,
84 mem::size_of::<u64>(),
85 )
86 });
87 if ret < 0 {
88 return errno_result();
89 }
90 if ret as usize != mem::size_of::<u64>() {
91 return Err(Error::new(libc::EIO));
92 }
93 Ok(())
94 }
95
96 pub fn read_count(&self) -> Result<u64> {
98 let mut buf: u64 = 0;
99 let ret = handle_eintr_errno!(unsafe {
103 read(
104 self.as_raw_descriptor(),
105 &mut buf as *mut u64 as *mut c_void,
106 mem::size_of::<u64>(),
107 )
108 });
109 if ret < 0 {
110 return errno_result();
111 }
112 if ret as usize != mem::size_of::<u64>() {
113 return Err(Error::new(libc::EIO));
114 }
115 Ok(buf)
116 }
117
118 pub fn signal(&self) -> Result<()> {
120 self.write_count(1)
121 }
122
123 pub fn wait(&self) -> Result<()> {
125 self.read_count().map(|_| ())
126 }
127
128 pub fn wait_timeout(&self, timeout: Duration) -> Result<EventWaitResult> {
130 let mut pfd = libc::pollfd {
131 fd: self.as_raw_descriptor(),
132 events: POLLIN,
133 revents: 0,
134 };
135 let timeoutspec: libc::timespec = duration_to_timespec(timeout);
136 let ret = unsafe {
139 libc::ppoll(
140 &mut pfd as *mut libc::pollfd,
141 1,
142 &timeoutspec,
143 ptr::null_mut(),
144 )
145 };
146 if ret < 0 {
147 return errno_result();
148 }
149
150 if pfd.revents == 0 {
152 return Ok(EventWaitResult::TimedOut);
153 }
154
155 self.wait()?;
156 Ok(EventWaitResult::Signaled)
157 }
158
159 pub fn reset(&self) -> Result<()> {
161 let _: EventWaitResult = self.wait_timeout(Duration::ZERO)?;
166 Ok(())
167 }
168
169 pub fn try_clone(&self) -> Result<PlatformEvent> {
172 self.event_handle
173 .try_clone()
174 .map(|event_handle| PlatformEvent { event_handle })
175 }
176}
177
178impl AsRawDescriptor for PlatformEvent {
179 fn as_raw_descriptor(&self) -> RawDescriptor {
180 self.event_handle.as_raw_descriptor()
181 }
182}
183
184impl FromRawDescriptor for PlatformEvent {
185 unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self {
186 PlatformEvent {
187 event_handle: SafeDescriptor::from_raw_descriptor(descriptor),
188 }
189 }
190}
191
192impl IntoRawDescriptor for PlatformEvent {
193 fn into_raw_descriptor(self) -> RawDescriptor {
194 self.event_handle.into_raw_descriptor()
195 }
196}
197
198impl From<PlatformEvent> for SafeDescriptor {
199 fn from(evt: PlatformEvent) -> Self {
200 evt.event_handle
201 }
202}
203
204impl From<SafeDescriptor> for PlatformEvent {
205 fn from(sd: SafeDescriptor) -> Self {
206 PlatformEvent { event_handle: sd }
207 }
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213 use crate::Event;
214 use crate::EventExt;
215
216 #[test]
217 fn new() {
218 Event::new().unwrap();
219 }
220
221 #[test]
222 fn read_write() {
223 let evt = Event::new().unwrap();
224 evt.write_count(55).unwrap();
225 assert_eq!(evt.read_count(), Ok(55));
226 }
227
228 #[test]
229 fn clone() {
230 let evt = Event::new().unwrap();
231 let evt_clone = evt.try_clone().unwrap();
232 evt.write_count(923).unwrap();
233 assert_eq!(evt_clone.read_count(), Ok(923));
234 }
235
236 #[test]
237 fn timeout() {
238 let evt = Event::new().expect("failed to create eventfd");
239 assert_eq!(
240 evt.wait_timeout(Duration::from_millis(1))
241 .expect("failed to read from eventfd with timeout"),
242 EventWaitResult::TimedOut
243 );
244 }
245}