mirror of https://github.com/aya-rs/aya
maps: add AsyncPerfMap
When the async_tokio or async_std features are enabled, AsyncPerfMap provides an async version of PerfMap which returns a future from read_events()pull/1/head
parent
4be0c45305
commit
fdc4dad5ff
@ -0,0 +1,108 @@
|
||||
use bytes::BytesMut;
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
ops::DerefMut,
|
||||
os::unix::prelude::{AsRawFd, RawFd},
|
||||
};
|
||||
|
||||
#[cfg(feature = "async_std")]
|
||||
use async_io::Async;
|
||||
|
||||
#[cfg(feature = "async_tokio")]
|
||||
use tokio::io::unix::AsyncFd;
|
||||
|
||||
use crate::maps::{
|
||||
perf_map::{Events, PerfBufferError, PerfMap, PerfMapBuffer, PerfMapError},
|
||||
Map, MapRefMut,
|
||||
};
|
||||
|
||||
pub struct AsyncPerfMap<T: DerefMut<Target = Map>> {
|
||||
perf_map: PerfMap<T>,
|
||||
}
|
||||
|
||||
impl<T: DerefMut<Target = Map>> AsyncPerfMap<T> {
|
||||
pub fn open(
|
||||
&mut self,
|
||||
index: u32,
|
||||
page_count: Option<usize>,
|
||||
) -> Result<AsyncPerfMapBuffer<T>, PerfMapError> {
|
||||
let buf = self.perf_map.open(index, page_count)?;
|
||||
let fd = buf.as_raw_fd();
|
||||
Ok(AsyncPerfMapBuffer {
|
||||
buf,
|
||||
|
||||
#[cfg(feature = "async_tokio")]
|
||||
async_fd: AsyncFd::new(fd)?,
|
||||
|
||||
#[cfg(feature = "async_std")]
|
||||
async_fd: Async::new(fd)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DerefMut<Target = Map>> AsyncPerfMap<T> {
|
||||
fn new(map: T) -> Result<AsyncPerfMap<T>, PerfMapError> {
|
||||
Ok(AsyncPerfMap {
|
||||
perf_map: PerfMap::new(map)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AsyncPerfMapBuffer<T: DerefMut<Target = Map>> {
|
||||
buf: PerfMapBuffer<T>,
|
||||
|
||||
#[cfg(feature = "async_tokio")]
|
||||
async_fd: AsyncFd<RawFd>,
|
||||
|
||||
#[cfg(feature = "async_std")]
|
||||
async_fd: Async<RawFd>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "async_tokio")]
|
||||
impl<T: DerefMut<Target = Map>> AsyncPerfMapBuffer<T> {
|
||||
pub async fn read_events(
|
||||
&mut self,
|
||||
buffers: &mut [BytesMut],
|
||||
) -> Result<Events, PerfBufferError> {
|
||||
loop {
|
||||
let mut guard = self.async_fd.readable_mut().await?;
|
||||
|
||||
match self.buf.read_events(buffers) {
|
||||
Ok(events) if events.read > 0 || events.lost > 0 => return Ok(events),
|
||||
Ok(_) => {
|
||||
guard.clear_ready();
|
||||
continue;
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "async_std")]
|
||||
impl<T: DerefMut<Target = Map>> AsyncPerfMapBuffer<T> {
|
||||
pub async fn read_events(
|
||||
&mut self,
|
||||
buffers: &mut [BytesMut],
|
||||
) -> Result<Events, PerfBufferError> {
|
||||
loop {
|
||||
if !self.buf.readable() {
|
||||
let _ = self.async_fd.readable().await?;
|
||||
}
|
||||
|
||||
match self.buf.read_events(buffers) {
|
||||
Ok(events) if events.read > 0 || events.lost > 0 => return Ok(events),
|
||||
Ok(_) => continue,
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<MapRefMut> for AsyncPerfMap<MapRefMut> {
|
||||
type Error = PerfMapError;
|
||||
|
||||
fn try_from(a: MapRefMut) -> Result<AsyncPerfMap<MapRefMut>, PerfMapError> {
|
||||
AsyncPerfMap::new(a)
|
||||
}
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
#[cfg(feature = "async")]
|
||||
mod async_perf_map;
|
||||
mod perf_buffer;
|
||||
mod perf_map;
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub use async_perf_map::*;
|
||||
pub use perf_buffer::*;
|
||||
pub use perf_map::*;
|
||||
|
Loading…
Reference in New Issue