1 // Copyright 2021 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::{convert::TryFrom, io, mem::size_of, sync::Arc}; 6 7 use anyhow::{ensure, Context}; 8 use sys_util::{EventFd, SafeDescriptor}; 9 10 use super::io_driver; 11 12 #[derive(Debug)] 13 pub struct Event { 14 fd: Arc<SafeDescriptor>, 15 } 16 17 impl Event { new() -> anyhow::Result<Event>18 pub fn new() -> anyhow::Result<Event> { 19 EventFd::new() 20 .map_err(io::Error::from) 21 .context("failed to create eventfd") 22 .and_then(Event::try_from) 23 } 24 next_val(&self) -> anyhow::Result<u64>25 pub async fn next_val(&self) -> anyhow::Result<u64> { 26 let mut buf = 0u64.to_ne_bytes(); 27 let count = io_driver::read(&self.fd, &mut buf, None).await?; 28 29 ensure!( 30 count == size_of::<u64>(), 31 io::Error::from(io::ErrorKind::UnexpectedEof) 32 ); 33 34 Ok(u64::from_ne_bytes(buf)) 35 } 36 notify(&self) -> anyhow::Result<()>37 pub async fn notify(&self) -> anyhow::Result<()> { 38 let buf = 1u64.to_ne_bytes(); 39 let count = io_driver::write(&self.fd, &buf, None).await?; 40 41 ensure!( 42 count == size_of::<u64>(), 43 io::Error::from(io::ErrorKind::WriteZero) 44 ); 45 46 Ok(()) 47 } 48 try_clone(&self) -> anyhow::Result<Event>49 pub fn try_clone(&self) -> anyhow::Result<Event> { 50 self.fd 51 .try_clone() 52 .map(|fd| Event { fd: Arc::new(fd) }) 53 .map_err(io::Error::from) 54 .map_err(From::from) 55 } 56 } 57 58 impl TryFrom<EventFd> for Event { 59 type Error = anyhow::Error; 60 try_from(evt: EventFd) -> anyhow::Result<Event>61 fn try_from(evt: EventFd) -> anyhow::Result<Event> { 62 io_driver::prepare(&evt)?; 63 Ok(Event { 64 fd: Arc::new(SafeDescriptor::from(evt)), 65 }) 66 } 67 } 68