1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2017 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::mem; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::ptr; 7*bb4ee6a4SAndroid Build Coastguard Worker use std::time::Duration; 8*bb4ee6a4SAndroid Build Coastguard Worker 9*bb4ee6a4SAndroid Build Coastguard Worker use libc::c_void; 10*bb4ee6a4SAndroid Build Coastguard Worker use libc::eventfd; 11*bb4ee6a4SAndroid Build Coastguard Worker use libc::read; 12*bb4ee6a4SAndroid Build Coastguard Worker use libc::write; 13*bb4ee6a4SAndroid Build Coastguard Worker use libc::POLLIN; 14*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize; 15*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize; 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard Worker use super::errno_result; 18*bb4ee6a4SAndroid Build Coastguard Worker use super::Error; 19*bb4ee6a4SAndroid Build Coastguard Worker use super::RawDescriptor; 20*bb4ee6a4SAndroid Build Coastguard Worker use super::Result; 21*bb4ee6a4SAndroid Build Coastguard Worker use crate::descriptor::AsRawDescriptor; 22*bb4ee6a4SAndroid Build Coastguard Worker use crate::descriptor::FromRawDescriptor; 23*bb4ee6a4SAndroid Build Coastguard Worker use crate::descriptor::IntoRawDescriptor; 24*bb4ee6a4SAndroid Build Coastguard Worker use crate::descriptor::SafeDescriptor; 25*bb4ee6a4SAndroid Build Coastguard Worker use crate::handle_eintr_errno; 26*bb4ee6a4SAndroid Build Coastguard Worker use crate::unix::duration_to_timespec; 27*bb4ee6a4SAndroid Build Coastguard Worker use crate::EventWaitResult; 28*bb4ee6a4SAndroid Build Coastguard Worker 29*bb4ee6a4SAndroid Build Coastguard Worker /// A safe wrapper around a Linux eventfd (man 2 eventfd). 30*bb4ee6a4SAndroid Build Coastguard Worker /// 31*bb4ee6a4SAndroid Build Coastguard Worker /// An eventfd is useful because it is sendable across processes and can be used for signaling in 32*bb4ee6a4SAndroid Build Coastguard Worker /// and out of the KVM API. They can also be polled like any other file descriptor. 33*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] 34*bb4ee6a4SAndroid Build Coastguard Worker #[serde(transparent)] 35*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) struct PlatformEvent { 36*bb4ee6a4SAndroid Build Coastguard Worker event_handle: SafeDescriptor, 37*bb4ee6a4SAndroid Build Coastguard Worker } 38*bb4ee6a4SAndroid Build Coastguard Worker 39*bb4ee6a4SAndroid Build Coastguard Worker /// Linux specific extensions to `Event`. 40*bb4ee6a4SAndroid Build Coastguard Worker pub trait EventExt { 41*bb4ee6a4SAndroid Build Coastguard Worker /// Adds `v` to the eventfd's count, blocking until this won't overflow the count. write_count(&self, v: u64) -> Result<()>42*bb4ee6a4SAndroid Build Coastguard Worker fn write_count(&self, v: u64) -> Result<()>; 43*bb4ee6a4SAndroid Build Coastguard Worker /// Blocks until the the eventfd's count is non-zero, then resets the count to zero. read_count(&self) -> Result<u64>44*bb4ee6a4SAndroid Build Coastguard Worker fn read_count(&self) -> Result<u64>; 45*bb4ee6a4SAndroid Build Coastguard Worker } 46*bb4ee6a4SAndroid Build Coastguard Worker 47*bb4ee6a4SAndroid Build Coastguard Worker impl EventExt for crate::Event { write_count(&self, v: u64) -> Result<()>48*bb4ee6a4SAndroid Build Coastguard Worker fn write_count(&self, v: u64) -> Result<()> { 49*bb4ee6a4SAndroid Build Coastguard Worker self.0.write_count(v) 50*bb4ee6a4SAndroid Build Coastguard Worker } 51*bb4ee6a4SAndroid Build Coastguard Worker read_count(&self) -> Result<u64>52*bb4ee6a4SAndroid Build Coastguard Worker fn read_count(&self) -> Result<u64> { 53*bb4ee6a4SAndroid Build Coastguard Worker self.0.read_count() 54*bb4ee6a4SAndroid Build Coastguard Worker } 55*bb4ee6a4SAndroid Build Coastguard Worker } 56*bb4ee6a4SAndroid Build Coastguard Worker 57*bb4ee6a4SAndroid Build Coastguard Worker impl PlatformEvent { 58*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a new blocking eventfd with an initial value of 0. new() -> Result<PlatformEvent>59*bb4ee6a4SAndroid Build Coastguard Worker pub fn new() -> Result<PlatformEvent> { 60*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 61*bb4ee6a4SAndroid Build Coastguard Worker // This is safe because eventfd merely allocated an eventfd for our process and we handle 62*bb4ee6a4SAndroid Build Coastguard Worker // the error case. 63*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { eventfd(0, 0) }; 64*bb4ee6a4SAndroid Build Coastguard Worker if ret < 0 { 65*bb4ee6a4SAndroid Build Coastguard Worker return errno_result(); 66*bb4ee6a4SAndroid Build Coastguard Worker } 67*bb4ee6a4SAndroid Build Coastguard Worker Ok(PlatformEvent { 68*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 69*bb4ee6a4SAndroid Build Coastguard Worker // This is safe because we checked ret for success and know the kernel gave us an fd 70*bb4ee6a4SAndroid Build Coastguard Worker // that we own. 71*bb4ee6a4SAndroid Build Coastguard Worker event_handle: unsafe { SafeDescriptor::from_raw_descriptor(ret) }, 72*bb4ee6a4SAndroid Build Coastguard Worker }) 73*bb4ee6a4SAndroid Build Coastguard Worker } 74*bb4ee6a4SAndroid Build Coastguard Worker 75*bb4ee6a4SAndroid Build Coastguard Worker /// See `EventExt::write_count`. write_count(&self, v: u64) -> Result<()>76*bb4ee6a4SAndroid Build Coastguard Worker pub fn write_count(&self, v: u64) -> Result<()> { 77*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 78*bb4ee6a4SAndroid Build Coastguard Worker // This is safe because we made this fd and the pointer we pass can not overflow because we 79*bb4ee6a4SAndroid Build Coastguard Worker // give the syscall's size parameter properly. 80*bb4ee6a4SAndroid Build Coastguard Worker let ret = handle_eintr_errno!(unsafe { 81*bb4ee6a4SAndroid Build Coastguard Worker write( 82*bb4ee6a4SAndroid Build Coastguard Worker self.as_raw_descriptor(), 83*bb4ee6a4SAndroid Build Coastguard Worker &v as *const u64 as *const c_void, 84*bb4ee6a4SAndroid Build Coastguard Worker mem::size_of::<u64>(), 85*bb4ee6a4SAndroid Build Coastguard Worker ) 86*bb4ee6a4SAndroid Build Coastguard Worker }); 87*bb4ee6a4SAndroid Build Coastguard Worker if ret < 0 { 88*bb4ee6a4SAndroid Build Coastguard Worker return errno_result(); 89*bb4ee6a4SAndroid Build Coastguard Worker } 90*bb4ee6a4SAndroid Build Coastguard Worker if ret as usize != mem::size_of::<u64>() { 91*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::new(libc::EIO)); 92*bb4ee6a4SAndroid Build Coastguard Worker } 93*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 94*bb4ee6a4SAndroid Build Coastguard Worker } 95*bb4ee6a4SAndroid Build Coastguard Worker 96*bb4ee6a4SAndroid Build Coastguard Worker /// See `EventExt::read_count`. read_count(&self) -> Result<u64>97*bb4ee6a4SAndroid Build Coastguard Worker pub fn read_count(&self) -> Result<u64> { 98*bb4ee6a4SAndroid Build Coastguard Worker let mut buf: u64 = 0; 99*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 100*bb4ee6a4SAndroid Build Coastguard Worker // This is safe because we made this fd and the pointer we pass can not overflow because 101*bb4ee6a4SAndroid Build Coastguard Worker // we give the syscall's size parameter properly. 102*bb4ee6a4SAndroid Build Coastguard Worker let ret = handle_eintr_errno!(unsafe { 103*bb4ee6a4SAndroid Build Coastguard Worker read( 104*bb4ee6a4SAndroid Build Coastguard Worker self.as_raw_descriptor(), 105*bb4ee6a4SAndroid Build Coastguard Worker &mut buf as *mut u64 as *mut c_void, 106*bb4ee6a4SAndroid Build Coastguard Worker mem::size_of::<u64>(), 107*bb4ee6a4SAndroid Build Coastguard Worker ) 108*bb4ee6a4SAndroid Build Coastguard Worker }); 109*bb4ee6a4SAndroid Build Coastguard Worker if ret < 0 { 110*bb4ee6a4SAndroid Build Coastguard Worker return errno_result(); 111*bb4ee6a4SAndroid Build Coastguard Worker } 112*bb4ee6a4SAndroid Build Coastguard Worker if ret as usize != mem::size_of::<u64>() { 113*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::new(libc::EIO)); 114*bb4ee6a4SAndroid Build Coastguard Worker } 115*bb4ee6a4SAndroid Build Coastguard Worker Ok(buf) 116*bb4ee6a4SAndroid Build Coastguard Worker } 117*bb4ee6a4SAndroid Build Coastguard Worker 118*bb4ee6a4SAndroid Build Coastguard Worker /// See `Event::signal`. signal(&self) -> Result<()>119*bb4ee6a4SAndroid Build Coastguard Worker pub fn signal(&self) -> Result<()> { 120*bb4ee6a4SAndroid Build Coastguard Worker self.write_count(1) 121*bb4ee6a4SAndroid Build Coastguard Worker } 122*bb4ee6a4SAndroid Build Coastguard Worker 123*bb4ee6a4SAndroid Build Coastguard Worker /// See `Event::wait`. wait(&self) -> Result<()>124*bb4ee6a4SAndroid Build Coastguard Worker pub fn wait(&self) -> Result<()> { 125*bb4ee6a4SAndroid Build Coastguard Worker self.read_count().map(|_| ()) 126*bb4ee6a4SAndroid Build Coastguard Worker } 127*bb4ee6a4SAndroid Build Coastguard Worker 128*bb4ee6a4SAndroid Build Coastguard Worker /// See `Event::wait_timeout`. wait_timeout(&self, timeout: Duration) -> Result<EventWaitResult>129*bb4ee6a4SAndroid Build Coastguard Worker pub fn wait_timeout(&self, timeout: Duration) -> Result<EventWaitResult> { 130*bb4ee6a4SAndroid Build Coastguard Worker let mut pfd = libc::pollfd { 131*bb4ee6a4SAndroid Build Coastguard Worker fd: self.as_raw_descriptor(), 132*bb4ee6a4SAndroid Build Coastguard Worker events: POLLIN, 133*bb4ee6a4SAndroid Build Coastguard Worker revents: 0, 134*bb4ee6a4SAndroid Build Coastguard Worker }; 135*bb4ee6a4SAndroid Build Coastguard Worker let timeoutspec: libc::timespec = duration_to_timespec(timeout); 136*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 137*bb4ee6a4SAndroid Build Coastguard Worker // Safe because this only modifies |pfd| and we check the return value 138*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { 139*bb4ee6a4SAndroid Build Coastguard Worker libc::ppoll( 140*bb4ee6a4SAndroid Build Coastguard Worker &mut pfd as *mut libc::pollfd, 141*bb4ee6a4SAndroid Build Coastguard Worker 1, 142*bb4ee6a4SAndroid Build Coastguard Worker &timeoutspec, 143*bb4ee6a4SAndroid Build Coastguard Worker ptr::null_mut(), 144*bb4ee6a4SAndroid Build Coastguard Worker ) 145*bb4ee6a4SAndroid Build Coastguard Worker }; 146*bb4ee6a4SAndroid Build Coastguard Worker if ret < 0 { 147*bb4ee6a4SAndroid Build Coastguard Worker return errno_result(); 148*bb4ee6a4SAndroid Build Coastguard Worker } 149*bb4ee6a4SAndroid Build Coastguard Worker 150*bb4ee6a4SAndroid Build Coastguard Worker // no return events (revents) means we got a timeout 151*bb4ee6a4SAndroid Build Coastguard Worker if pfd.revents == 0 { 152*bb4ee6a4SAndroid Build Coastguard Worker return Ok(EventWaitResult::TimedOut); 153*bb4ee6a4SAndroid Build Coastguard Worker } 154*bb4ee6a4SAndroid Build Coastguard Worker 155*bb4ee6a4SAndroid Build Coastguard Worker self.wait()?; 156*bb4ee6a4SAndroid Build Coastguard Worker Ok(EventWaitResult::Signaled) 157*bb4ee6a4SAndroid Build Coastguard Worker } 158*bb4ee6a4SAndroid Build Coastguard Worker 159*bb4ee6a4SAndroid Build Coastguard Worker /// See `Event::reset`. reset(&self) -> Result<()>160*bb4ee6a4SAndroid Build Coastguard Worker pub fn reset(&self) -> Result<()> { 161*bb4ee6a4SAndroid Build Coastguard Worker // If the eventfd is currently signaled (counter > 0), `wait_timeout()` will `read()` it to 162*bb4ee6a4SAndroid Build Coastguard Worker // reset the count. Otherwise (if the eventfd is not signaled), `wait_timeout()` will return 163*bb4ee6a4SAndroid Build Coastguard Worker // immediately since we pass a zero duration. We don't care about the EventWaitResult; we 164*bb4ee6a4SAndroid Build Coastguard Worker // just want a non-blocking read to reset the counter. 165*bb4ee6a4SAndroid Build Coastguard Worker let _: EventWaitResult = self.wait_timeout(Duration::ZERO)?; 166*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 167*bb4ee6a4SAndroid Build Coastguard Worker } 168*bb4ee6a4SAndroid Build Coastguard Worker 169*bb4ee6a4SAndroid Build Coastguard Worker /// Clones this eventfd, internally creating a new file descriptor. The new eventfd will share 170*bb4ee6a4SAndroid Build Coastguard Worker /// the same underlying count within the kernel. try_clone(&self) -> Result<PlatformEvent>171*bb4ee6a4SAndroid Build Coastguard Worker pub fn try_clone(&self) -> Result<PlatformEvent> { 172*bb4ee6a4SAndroid Build Coastguard Worker self.event_handle 173*bb4ee6a4SAndroid Build Coastguard Worker .try_clone() 174*bb4ee6a4SAndroid Build Coastguard Worker .map(|event_handle| PlatformEvent { event_handle }) 175*bb4ee6a4SAndroid Build Coastguard Worker } 176*bb4ee6a4SAndroid Build Coastguard Worker } 177*bb4ee6a4SAndroid Build Coastguard Worker 178*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for PlatformEvent { as_raw_descriptor(&self) -> RawDescriptor179*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptor(&self) -> RawDescriptor { 180*bb4ee6a4SAndroid Build Coastguard Worker self.event_handle.as_raw_descriptor() 181*bb4ee6a4SAndroid Build Coastguard Worker } 182*bb4ee6a4SAndroid Build Coastguard Worker } 183*bb4ee6a4SAndroid Build Coastguard Worker 184*bb4ee6a4SAndroid Build Coastguard Worker impl FromRawDescriptor for PlatformEvent { from_raw_descriptor(descriptor: RawDescriptor) -> Self185*bb4ee6a4SAndroid Build Coastguard Worker unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self { 186*bb4ee6a4SAndroid Build Coastguard Worker PlatformEvent { 187*bb4ee6a4SAndroid Build Coastguard Worker event_handle: SafeDescriptor::from_raw_descriptor(descriptor), 188*bb4ee6a4SAndroid Build Coastguard Worker } 189*bb4ee6a4SAndroid Build Coastguard Worker } 190*bb4ee6a4SAndroid Build Coastguard Worker } 191*bb4ee6a4SAndroid Build Coastguard Worker 192*bb4ee6a4SAndroid Build Coastguard Worker impl IntoRawDescriptor for PlatformEvent { into_raw_descriptor(self) -> RawDescriptor193*bb4ee6a4SAndroid Build Coastguard Worker fn into_raw_descriptor(self) -> RawDescriptor { 194*bb4ee6a4SAndroid Build Coastguard Worker self.event_handle.into_raw_descriptor() 195*bb4ee6a4SAndroid Build Coastguard Worker } 196*bb4ee6a4SAndroid Build Coastguard Worker } 197*bb4ee6a4SAndroid Build Coastguard Worker 198*bb4ee6a4SAndroid Build Coastguard Worker impl From<PlatformEvent> for SafeDescriptor { from(evt: PlatformEvent) -> Self199*bb4ee6a4SAndroid Build Coastguard Worker fn from(evt: PlatformEvent) -> Self { 200*bb4ee6a4SAndroid Build Coastguard Worker evt.event_handle 201*bb4ee6a4SAndroid Build Coastguard Worker } 202*bb4ee6a4SAndroid Build Coastguard Worker } 203*bb4ee6a4SAndroid Build Coastguard Worker 204*bb4ee6a4SAndroid Build Coastguard Worker impl From<SafeDescriptor> for PlatformEvent { from(sd: SafeDescriptor) -> Self205*bb4ee6a4SAndroid Build Coastguard Worker fn from(sd: SafeDescriptor) -> Self { 206*bb4ee6a4SAndroid Build Coastguard Worker PlatformEvent { event_handle: sd } 207*bb4ee6a4SAndroid Build Coastguard Worker } 208*bb4ee6a4SAndroid Build Coastguard Worker } 209*bb4ee6a4SAndroid Build Coastguard Worker 210*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)] 211*bb4ee6a4SAndroid Build Coastguard Worker mod tests { 212*bb4ee6a4SAndroid Build Coastguard Worker use super::*; 213*bb4ee6a4SAndroid Build Coastguard Worker use crate::Event; 214*bb4ee6a4SAndroid Build Coastguard Worker use crate::EventExt; 215*bb4ee6a4SAndroid Build Coastguard Worker 216*bb4ee6a4SAndroid Build Coastguard Worker #[test] new()217*bb4ee6a4SAndroid Build Coastguard Worker fn new() { 218*bb4ee6a4SAndroid Build Coastguard Worker Event::new().unwrap(); 219*bb4ee6a4SAndroid Build Coastguard Worker } 220*bb4ee6a4SAndroid Build Coastguard Worker 221*bb4ee6a4SAndroid Build Coastguard Worker #[test] read_write()222*bb4ee6a4SAndroid Build Coastguard Worker fn read_write() { 223*bb4ee6a4SAndroid Build Coastguard Worker let evt = Event::new().unwrap(); 224*bb4ee6a4SAndroid Build Coastguard Worker evt.write_count(55).unwrap(); 225*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(evt.read_count(), Ok(55)); 226*bb4ee6a4SAndroid Build Coastguard Worker } 227*bb4ee6a4SAndroid Build Coastguard Worker 228*bb4ee6a4SAndroid Build Coastguard Worker #[test] clone()229*bb4ee6a4SAndroid Build Coastguard Worker fn clone() { 230*bb4ee6a4SAndroid Build Coastguard Worker let evt = Event::new().unwrap(); 231*bb4ee6a4SAndroid Build Coastguard Worker let evt_clone = evt.try_clone().unwrap(); 232*bb4ee6a4SAndroid Build Coastguard Worker evt.write_count(923).unwrap(); 233*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(evt_clone.read_count(), Ok(923)); 234*bb4ee6a4SAndroid Build Coastguard Worker } 235*bb4ee6a4SAndroid Build Coastguard Worker 236*bb4ee6a4SAndroid Build Coastguard Worker #[test] timeout()237*bb4ee6a4SAndroid Build Coastguard Worker fn timeout() { 238*bb4ee6a4SAndroid Build Coastguard Worker let evt = Event::new().expect("failed to create eventfd"); 239*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 240*bb4ee6a4SAndroid Build Coastguard Worker evt.wait_timeout(Duration::from_millis(1)) 241*bb4ee6a4SAndroid Build Coastguard Worker .expect("failed to read from eventfd with timeout"), 242*bb4ee6a4SAndroid Build Coastguard Worker EventWaitResult::TimedOut 243*bb4ee6a4SAndroid Build Coastguard Worker ); 244*bb4ee6a4SAndroid Build Coastguard Worker } 245*bb4ee6a4SAndroid Build Coastguard Worker } 246