Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ targets = [
libc = { version = "0.2.186", features = ["extra_traits"] }
bitflags = "2.3.3"
cfg-if = "1.0"
pin-utils = { version = "0.1.0", optional = true }
pin-project-lite = { version = "0.2", optional = true }
memoffset = { version = "0.9", optional = true }

[features]
default = []

acct = []
aio = ["pin-utils"]
aio = ["pin-project-lite"]
dir = ["fs"]
env = []
event = ["poll"]
Expand Down
116 changes: 62 additions & 54 deletions src/sys/aio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ use std::{
};

use libc::off_t;
#[allow(deprecated)]
use pin_utils::unsafe_pinned;
use pin_project_lite::pin_project;

use crate::{
errno::Errno,
Expand Down Expand Up @@ -119,8 +118,6 @@ struct AioCb<'a> {

#[allow(deprecated)]
impl<'a> AioCb<'a> {
pin_utils::unsafe_unpinned!(aiocb: LibcAiocb);

fn aio_return(mut self: Pin<&mut Self>) -> Result<usize> {
self.in_progress = false;
unsafe {
Expand Down Expand Up @@ -164,7 +161,7 @@ impl<'a> AioCb<'a> {
}

fn error(self: Pin<&mut Self>) -> Result<()> {
let r = unsafe { libc::aio_error(&self.aiocb().0) };
let r = unsafe { libc::aio_error(&self.aiocb.0) };
match r {
0 => Ok(()),
num if num > 0 => Err(Errno::from_raw(num)),
Expand Down Expand Up @@ -366,11 +363,11 @@ pub trait Aio {
macro_rules! aio_methods {
() => {
fn cancel(self: Pin<&mut Self>) -> Result<AioCancelStat> {
self.aiocb().cancel()
self.project().aiocb.cancel()
}

fn error(self: Pin<&mut Self>) -> Result<()> {
self.aiocb().error()
self.project().aiocb.error()
}

fn fd(&self) -> BorrowedFd<'a> {
Expand Down Expand Up @@ -399,18 +396,20 @@ macro_rules! aio_methods {
aio_methods!();

fn aio_return(self: Pin<&mut Self>) -> Result<<Self as Aio>::Output> {
self.aiocb().aio_return()
self.project().aiocb.aio_return()
}

fn submit(mut self: Pin<&mut Self>) -> Result<()> {
let p: *mut libc::aiocb = &mut self.as_mut().aiocb().aiocb.0;
let p: *mut libc::aiocb =
&mut self.as_mut().project().aiocb.get_mut().aiocb.0;
Errno::result({ unsafe { libc::$func(p) } }).map(|_| {
self.aiocb().set_in_progress();
self.as_mut().project().aiocb.set_in_progress();
})
}
};
}

pin_project! {
/// An asynchronous version of `fsync(2)`.
///
/// # References
Expand All @@ -435,17 +434,18 @@ macro_rules! aio_methods {
/// }
/// aiof.as_mut().aio_return().expect("aio_fsync failed late");
/// ```
#[derive(Debug)]
#[repr(transparent)]
pub struct AioFsync<'a> {
aiocb: AioCb<'a>,
_pin: PhantomPinned,
#[derive(Debug)]
#[repr(transparent)]
pub struct AioFsync<'a> {
#[pin]
aiocb: AioCb<'a>,
#[pin]
_pin: PhantomPinned,
}
}

#[allow(deprecated)]
impl<'a> AioFsync<'a> {
unsafe_pinned!(aiocb: AioCb<'a>);

/// Returns the operation's fsync mode: data and metadata or data only?
pub fn mode(&self) -> AioFsyncMode {
AioFsyncMode::try_from(self.aiocb.aiocb.0.aio_lio_opcode).unwrap()
Expand Down Expand Up @@ -486,15 +486,15 @@ impl<'a> Aio for AioFsync<'a> {
aio_methods!();

fn aio_return(self: Pin<&mut Self>) -> Result<()> {
self.aiocb().aio_return().map(drop)
self.project().aiocb.aio_return().map(drop)
}

fn submit(mut self: Pin<&mut Self>) -> Result<()> {
let aiocb = &mut self.as_mut().aiocb().aiocb.0;
let aiocb = &mut self.as_mut().project().aiocb.get_mut().aiocb.0;
let mode = mem::replace(&mut aiocb.aio_lio_opcode, 0);
let p: *mut libc::aiocb = aiocb;
Errno::result(unsafe { libc::aio_fsync(mode, p) }).map(|_| {
self.aiocb().set_in_progress();
self.as_mut().project().aiocb.set_in_progress();
})
}
}
Expand All @@ -507,6 +507,7 @@ impl AsRef<libc::aiocb> for AioFsync<'_> {
}
}

pin_project! {
/// Asynchronously reads from a file descriptor into a buffer
///
/// # References
Expand Down Expand Up @@ -548,18 +549,19 @@ impl AsRef<libc::aiocb> for AioFsync<'_> {
/// }
/// assert_eq!(rbuf, b"cdef");
/// ```
#[derive(Debug)]
#[repr(transparent)]
pub struct AioRead<'a> {
aiocb: AioCb<'a>,
_data: PhantomData<&'a [u8]>,
_pin: PhantomPinned,
#[derive(Debug)]
#[repr(transparent)]
pub struct AioRead<'a> {
#[pin]
aiocb: AioCb<'a>,
_data: PhantomData<&'a [u8]>,
#[pin]
_pin: PhantomPinned,
}
}

#[allow(deprecated)]
impl<'a> AioRead<'a> {
unsafe_pinned!(aiocb: AioCb<'a>);

/// Returns the requested length of the aio operation in bytes
///
/// This method returns the *requested* length of the operation. To get the
Expand Down Expand Up @@ -623,6 +625,8 @@ impl AsRef<libc::aiocb> for AioRead<'_> {
}
}

#[cfg(target_os = "freebsd")]
pin_project! {
/// Asynchronously reads from a file descriptor into a scatter/gather list of buffers.
///
/// # References
Expand Down Expand Up @@ -668,20 +672,20 @@ impl AsRef<libc::aiocb> for AioRead<'_> {
/// assert_eq!(rbuf0, b"cdef");
/// assert_eq!(rbuf1, b"12");
/// ```
#[cfg(target_os = "freebsd")]
#[derive(Debug)]
#[repr(transparent)]
pub struct AioReadv<'a> {
aiocb: AioCb<'a>,
_data: PhantomData<&'a [&'a [u8]]>,
_pin: PhantomPinned,
#[derive(Debug)]
#[repr(transparent)]
pub struct AioReadv<'a> {
#[pin]
aiocb: AioCb<'a>,
_data: PhantomData<&'a [&'a [u8]]>,
#[pin]
_pin: PhantomPinned,
}
}

#[allow(deprecated)]
#[cfg(target_os = "freebsd")]
impl<'a> AioReadv<'a> {
unsafe_pinned!(aiocb: AioCb<'a>);

/// Returns the number of buffers the operation will read into.
pub fn iovlen(&self) -> usize {
self.aiocb.aiocb.0.aio_nbytes
Expand Down Expand Up @@ -748,6 +752,7 @@ impl AsRef<libc::aiocb> for AioReadv<'_> {
}
}

pin_project! {
/// Asynchronously writes from a buffer to a file descriptor
///
/// # References
Expand Down Expand Up @@ -781,18 +786,19 @@ impl AsRef<libc::aiocb> for AioReadv<'_> {
/// }
/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len());
/// ```
#[derive(Debug)]
#[repr(transparent)]
pub struct AioWrite<'a> {
aiocb: AioCb<'a>,
_data: PhantomData<&'a [u8]>,
_pin: PhantomPinned,
#[derive(Debug)]
#[repr(transparent)]
pub struct AioWrite<'a> {
#[pin]
aiocb: AioCb<'a>,
_data: PhantomData<&'a [u8]>,
#[pin]
_pin: PhantomPinned,
}
}

#[allow(deprecated)]
impl<'a> AioWrite<'a> {
unsafe_pinned!(aiocb: AioCb<'a>);

/// Returns the requested length of the aio operation in bytes
///
/// This method returns the *requested* length of the operation. To get the
Expand Down Expand Up @@ -860,6 +866,8 @@ impl AsRef<libc::aiocb> for AioWrite<'_> {
}
}

#[cfg(target_os = "freebsd")]
pin_project! {
/// Asynchronously writes from a scatter/gather list of buffers to a file descriptor.
///
/// # References
Expand Down Expand Up @@ -898,20 +906,20 @@ impl AsRef<libc::aiocb> for AioWrite<'_> {
/// }
/// assert_eq!(aiow.as_mut().aio_return().unwrap(), len);
/// ```
#[cfg(target_os = "freebsd")]
#[derive(Debug)]
#[repr(transparent)]
pub struct AioWritev<'a> {
aiocb: AioCb<'a>,
_data: PhantomData<&'a [&'a [u8]]>,
_pin: PhantomPinned,
#[derive(Debug)]
#[repr(transparent)]
pub struct AioWritev<'a> {
#[pin]
aiocb: AioCb<'a>,
_data: PhantomData<&'a [&'a [u8]]>,
#[pin]
_pin: PhantomPinned,
}
}

#[allow(deprecated)]
#[cfg(target_os = "freebsd")]
impl<'a> AioWritev<'a> {
unsafe_pinned!(aiocb: AioCb<'a>);

/// Returns the number of buffers the operation will read into.
pub fn iovlen(&self) -> usize {
self.aiocb.aiocb.0.aio_nbytes
Expand Down
Loading