|
@@ -4,6 +4,10 @@ use std::{
|
|
|
os::fd::{AsRawFd, RawFd},
|
|
|
};
|
|
|
|
|
|
+// See https://doc.rust-lang.org/cargo/reference/features.html#mutually-exclusive-features.
|
|
|
+//
|
|
|
+// We should eventually split async functionality out into separate crates "aya-async-tokio" and
|
|
|
+// "async-async-std". Presently we arbitrarily choose tokio over async-std when both are requested.
|
|
|
#[cfg(all(not(feature = "async_tokio"), feature = "async_std"))]
|
|
|
use async_io::Async;
|
|
|
|
|
@@ -98,16 +102,17 @@ impl<T: BorrowMut<MapData> + Borrow<MapData>> AsyncPerfEventArray<T> {
|
|
|
index: u32,
|
|
|
page_count: Option<usize>,
|
|
|
) -> Result<AsyncPerfEventArrayBuffer<T>, PerfBufferError> {
|
|
|
- let buf = self.perf_map.open(index, page_count)?;
|
|
|
+ let Self { perf_map } = self;
|
|
|
+ let buf = perf_map.open(index, page_count)?;
|
|
|
let fd = buf.as_raw_fd();
|
|
|
Ok(AsyncPerfEventArrayBuffer {
|
|
|
buf,
|
|
|
|
|
|
#[cfg(feature = "async_tokio")]
|
|
|
- async_fd: AsyncFd::new(fd)?,
|
|
|
+ async_tokio_fd: AsyncFd::new(fd)?,
|
|
|
|
|
|
#[cfg(all(not(feature = "async_tokio"), feature = "async_std"))]
|
|
|
- async_fd: Async::new(fd)?,
|
|
|
+ async_std_fd: Async::new(fd)?,
|
|
|
})
|
|
|
}
|
|
|
}
|
|
@@ -131,13 +136,12 @@ pub struct AsyncPerfEventArrayBuffer<T> {
|
|
|
buf: PerfEventArrayBuffer<T>,
|
|
|
|
|
|
#[cfg(feature = "async_tokio")]
|
|
|
- async_fd: AsyncFd<RawFd>,
|
|
|
+ async_tokio_fd: AsyncFd<RawFd>,
|
|
|
|
|
|
#[cfg(all(not(feature = "async_tokio"), feature = "async_std"))]
|
|
|
- async_fd: Async<RawFd>,
|
|
|
+ async_std_fd: Async<RawFd>,
|
|
|
}
|
|
|
|
|
|
-#[cfg(feature = "async_tokio")]
|
|
|
impl<T: BorrowMut<MapData> + Borrow<MapData>> AsyncPerfEventArrayBuffer<T> {
|
|
|
/// Reads events from the buffer.
|
|
|
///
|
|
@@ -152,46 +156,30 @@ impl<T: BorrowMut<MapData> + Borrow<MapData>> AsyncPerfEventArrayBuffer<T> {
|
|
|
&mut self,
|
|
|
buffers: &mut [BytesMut],
|
|
|
) -> Result<Events, PerfBufferError> {
|
|
|
+ let Self {
|
|
|
+ buf,
|
|
|
+ #[cfg(feature = "async_tokio")]
|
|
|
+ async_tokio_fd,
|
|
|
+ #[cfg(all(not(feature = "async_tokio"), feature = "async_std"))]
|
|
|
+ async_std_fd,
|
|
|
+ } = self;
|
|
|
loop {
|
|
|
- let mut guard = self.async_fd.readable_mut().await?;
|
|
|
+ #[cfg(feature = "async_tokio")]
|
|
|
+ let mut guard = async_tokio_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(all(not(feature = "async_tokio"), feature = "async_std"))]
|
|
|
+ if !buf.readable() {
|
|
|
+ async_std_fd.readable().await?;
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
-#[cfg(all(not(feature = "async_tokio"), feature = "async_std"))]
|
|
|
-impl<T: BorrowMut<MapData> + Borrow<MapData>> AsyncPerfEventArrayBuffer<T> {
|
|
|
- /// Reads events from the buffer.
|
|
|
- ///
|
|
|
- /// This method reads events into the provided slice of buffers, filling
|
|
|
- /// each buffer in order stopping when there are no more events to read or
|
|
|
- /// all the buffers have been filled.
|
|
|
- ///
|
|
|
- /// Returns the number of events read and the number of events lost. Events
|
|
|
- /// are lost when user space doesn't read events fast enough and the ring
|
|
|
- /// buffer fills up.
|
|
|
- pub async fn read_events(
|
|
|
- &mut self,
|
|
|
- buffers: &mut [BytesMut],
|
|
|
- ) -> Result<Events, PerfBufferError> {
|
|
|
- loop {
|
|
|
- if !self.buf.readable() {
|
|
|
- let _ = self.async_fd.readable().await?;
|
|
|
+ let events = buf.read_events(buffers)?;
|
|
|
+ const EMPTY: Events = Events { read: 0, lost: 0 };
|
|
|
+ if events != EMPTY {
|
|
|
+ break Ok(events);
|
|
|
}
|
|
|
|
|
|
- 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),
|
|
|
- }
|
|
|
+ #[cfg(feature = "async_tokio")]
|
|
|
+ guard.clear_ready();
|
|
|
}
|
|
|
}
|
|
|
}
|