blob: 81052109489ce46cce052dfcdfb62e558904397a [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::io_ext::async_from;
use crate::{AsyncError, AsyncResult, IntoAsync, IoSourceExt};
use std::convert::TryFrom;
use sys_util::EventFd;
/// An async version of `sys_util::EventFd`.
pub struct EventAsync {
io_source: Box<dyn IoSourceExt<EventFd>>,
}
impl EventAsync {
#[cfg(test)]
pub(crate) fn new_poll(event: EventFd) -> AsyncResult<EventAsync> {
Ok(EventAsync {
io_source: crate::io_ext::async_poll_from(event)?,
})
}
#[cfg(test)]
pub(crate) fn new_uring(event: EventFd) -> AsyncResult<EventAsync> {
Ok(EventAsync {
io_source: crate::io_ext::async_uring_from(event)?,
})
}
/// Gets the next value from the eventfd.
#[allow(dead_code)]
pub async fn next_val(&self) -> AsyncResult<u64> {
self.io_source.read_u64().await
}
}
impl TryFrom<EventFd> for EventAsync {
type Error = AsyncError;
/// Creates a new EventAsync wrapper around the provided eventfd.
fn try_from(event: EventFd) -> AsyncResult<Self> {
Ok(EventAsync {
io_source: async_from(event)?,
})
}
}
impl IntoAsync for EventFd {}
#[cfg(test)]
mod tests {
use super::*;
use futures::pin_mut;
use std::convert::TryInto;
#[test]
fn next_val_reads_value() {
async fn go(event: EventFd) -> u64 {
let event_async: EventAsync = event.try_into().unwrap();
event_async.next_val().await.unwrap()
}
let eventfd = EventFd::new().unwrap();
eventfd.write(0xaa).unwrap();
let fut = go(eventfd);
pin_mut!(fut);
let val = crate::run_executor(crate::RunOne::new(fut)).unwrap();
assert_eq!(val, 0xaa);
}
#[test]
fn next_val_reads_value_poll_and_ring() {
async fn go(event_async: EventAsync) -> u64 {
event_async.next_val().await.unwrap()
}
let eventfd = EventFd::new().unwrap();
eventfd.write(0xaa).unwrap();
let fut = go(EventAsync::new_uring(eventfd).unwrap());
pin_mut!(fut);
let val = crate::run_one_uring(fut).unwrap();
assert_eq!(val, 0xaa);
let eventfd = EventFd::new().unwrap();
eventfd.write(0xaa).unwrap();
let fut = go(EventAsync::new_poll(eventfd).unwrap());
pin_mut!(fut);
let val = crate::run_one_poll(fut).unwrap();
assert_eq!(val, 0xaa);
}
}