Skip to content

Commit

Permalink
Rewrite the aio module
Browse files Browse the repository at this point in the history
The existing AIO implementation has some problems:
1) The in_progress field is checked at runtime, not compile time.
2) The mutable field is checked at runtime, not compile time.
3) A downstream lio_listio user must store extra state to track whether
   the whole operation is partially, completely, or not at all
   submitted.
4) Nix does heap allocation itself, rather than allowing the caller to
   choose it.  This can result in double (or triple, or quadruple)
   boxing.
5) There's no easy way to use lio_listio to submit multiple operations with
   a single syscall, but poll each individually.
6) The lio_listio usage is far from transparent and zero-cost.
7) No aio_readv or aio_writev support.
8) priority has type c_int; should be i32
9) aio_return should return a usize instead of an isize, since it only
   uses negative values to indicate errors, which Rust represents via
   the Result type.

This rewrite solves several problems:
1) Unsolved.  I don't think it can be solved without something like
   C++'s guaranteed type elision.  It might require changing the
   signature of Future::poll too.
2) Solved.
3) Solved, by the new in_progress method and by removing the complicated
   lio_listio resubmit code.
4) Solved.
5) Solved.
6) Solved, by removing the lio_listo resubmit code.  It can be
   reimplemented downstream if necessary.  Or even in Nix, but it
   doesn't fit Nix's theme of zero-cost abstractions.
7) Solved.
8) Solved.
9) Solved.

The rewrite includes functions that don't work on FreeBSD, so add CI
testing for FreeBSD 14 too.

By default only enable tests that will pass on FreeBSD 12.3.  But run a
CI job on FreeBSD 14 and set a flag that will enable such tests.
  • Loading branch information
asomers committed May 14, 2022
1 parent 6f57f2e commit f9e1922
Show file tree
Hide file tree
Showing 9 changed files with 1,570 additions and 1,525 deletions.
13 changes: 10 additions & 3 deletions .cirrus.yml
Expand Up @@ -36,11 +36,18 @@ test: &TEST
# 64-bit kernel and in a 64-bit environment. Our tests don't execute any of
# the system's binaries, so the environment shouldn't matter.
task:
name: FreeBSD amd64 & i686
env:
TARGET: x86_64-unknown-freebsd
freebsd_instance:
image: freebsd-12-3-release-amd64
matrix:
- name: FreeBSD 12 amd64 & i686
freebsd_instance:
image: freebsd-12-3-release-amd64
- name: FreeBSD 14 amd64 & i686
freebsd_instance:
image_family: freebsd-14-0-snap
# Enable tests that would fail on FreeBSD 12
RUSTFLAGS: --cfg fbsd14 -D warnings
RUSTDOCFLAGS: --cfg fbsd14
setup_script:
- kldload mqueuefs
- fetch https://sh.rustup.rs -o rustup.sh
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,14 +6,30 @@ This project adheres to [Semantic Versioning](https://semver.org/).
## [Unreleased] - ReleaseDate
### Added

- Added `aio_writev` and `aio_readv`.
(#[1713](https://github.com/nix-rust/nix/pull/1713))

- impl From<SockaddrIn> for std::net::SocketAddrV4 and
impl From<SockaddrIn6> for std::net::SocketAddrV6.
(#[1711](https://github.com/nix-rust/nix/pull/1711))

### Changed

- Rewrote the aio module. The new module:
* Does more type checking at compile time rather than runtime.
* Gives the caller control over whether and when to `Box` an aio operation.
* Changes the type of the `priority` arguments to `i32`.
* Changes the return type of `aio_return` to `usize`.
(#[1713](https://github.com/nix-rust/nix/pull/1713))

### Fixed
### Removed

- Removed support for resubmitting partially complete `lio_listio` operations.
It was too complicated, and didn't fit Nix's theme of zero-cost abstractions.
Instead, it can be reimplemented downstream.
(#[1713](https://github.com/nix-rust/nix/pull/1713))

## [0.24.1] - 2022-04-22
### Added
### Changed
Expand Down
9 changes: 3 additions & 6 deletions Cargo.toml
Expand Up @@ -27,9 +27,10 @@ targets = [
]

[dependencies]
libc = { version = "0.2.124", features = [ "extra_traits" ] }
libc = { git = "http://github.com/rust-lang/libc.git", rev = "cd99f681181c310abfba742aef11115d2eff03dc", features = [ "extra_traits" ] }
bitflags = "1.1"
cfg-if = "1.0"
pin-utils = { version = "0.1.0", optional = true }

[target.'cfg(not(target_os = "redox"))'.dependencies]
memoffset = { version = "0.6.3", optional = true }
Expand All @@ -44,7 +45,7 @@ default = [
]

acct = []
aio = []
aio = ["pin-utils"]
dir = ["fs"]
env = []
event = []
Expand Down Expand Up @@ -102,10 +103,6 @@ path = "test/sys/test_aio_drop.rs"
name = "test-clearenv"
path = "test/test_clearenv.rs"

[[test]]
name = "test-lio-listio-resubmit"
path = "test/sys/test_lio_listio_resubmit.rs"

[[test]]
name = "test-mount"
path = "test/test_mount.rs"
Expand Down
3 changes: 2 additions & 1 deletion bors.toml
Expand Up @@ -5,7 +5,8 @@ status = [
"Android i686",
"Android x86_64",
"DragonFly BSD x86_64",
"FreeBSD amd64 & i686",
"FreeBSD 12 amd64 & i686",
"FreeBSD 14 amd64 & i686",
"Fuchsia x86_64",
"Linux MIPS",
"Linux MIPS64 el",
Expand Down
8 changes: 4 additions & 4 deletions src/fcntl.rs
Expand Up @@ -742,8 +742,8 @@ impl SpacectlRange {
///
/// # Example
///
// no_run because it fails to link until FreeBSD 14.0
/// ```no_run
#[cfg_attr(fbsd14, doc = " ```")]
#[cfg_attr(not(fbsd14), doc = " ```no_run")]
/// # use std::io::Write;
/// # use std::os::unix::fs::FileExt;
/// # use std::os::unix::io::AsRawFd;
Expand Down Expand Up @@ -788,8 +788,8 @@ pub fn fspacectl(fd: RawFd, range: SpacectlRange) -> Result<SpacectlRange> {
///
/// # Example
///
// no_run because it fails to link until FreeBSD 14.0
/// ```no_run
#[cfg_attr(fbsd14, doc = " ```")]
#[cfg_attr(not(fbsd14), doc = " ```no_run")]
/// # use std::io::Write;
/// # use std::os::unix::fs::FileExt;
/// # use std::os::unix::io::AsRawFd;
Expand Down

0 comments on commit f9e1922

Please sign in to comment.