Skip to content

7992: io: AioSource now employs IO Safety#85

Open
martin-augment wants to merge 1 commit intomasterfrom
pr-7992-2026-03-29-19-45-14
Open

7992: io: AioSource now employs IO Safety#85
martin-augment wants to merge 1 commit intomasterfrom
pr-7992-2026-03-29-19-45-14

Conversation

@martin-augment
Copy link
Copy Markdown
Owner

7992: To review by AI

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 29, 2026

Walkthrough

This pull request refactors file descriptor handling across Tokio to use borrowed and owned file descriptor types from the standard library instead of raw file descriptor primitives. The changes include: updating Cargo dependencies (mio to 1.2.0, nix dev-dependency to 0.31.0, mio-aio to major version 2), modifying the AioSource::register signature to accept BorrowedFd<'_> instead of RawFd, and updating test helpers and implementations to pass OwnedFd and BorrowedFd values directly rather than extracting raw file descriptors. The modifications preserve existing control flow and error handling behavior while improving type safety.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pr-7992-2026-03-29-19-45-14

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates several dependencies, including mio to 1.2.0, nix to 0.31.0, and mio-aio to version 2. Additionally, it refactors the AIO source registration and various test utilities to use safer file descriptor abstractions like BorrowedFd and OwnedFd from std::os::fd instead of RawFd. I have no feedback to provide.

@claude
Copy link
Copy Markdown

claude bot commented Mar 29, 2026

PR Review - io: AioSource now employs IO Safety. This PR migrates AioSource from RawFd/AsRawFd to the IO-safe equivalents BorrowedFd/OwnedFd/AsFd (Rust 1.63+). Bumps mio to 1.2.0, nix to 0.31.0, mio-aio to v2. Overall well-scoped and correct. Key observations: (1) Correctness: LlSource/LioSource calling .as_raw_fd() on BorrowedFd for libc::sigevent is the idiomatic bridge between IO-safe Rust and raw C APIs. BorrowedFd lifetime guarantees validity for the call. (2) mem::forget ordering in io_async_fd_memory_leak.rs is correct - set_nonblocking borrow released before forget runs. (3) Retained RawFd/AsRawFd imports in the leak test are intentional and not dead code. (4) Breaking API change: AioSource::register signature change from RawFd to BorrowedFd is breaking for downstream implementors - even though FreeBSD-only and behind tokio_unstable, should be documented in CHANGELOG. (5) MioSource::reregister delegating to register is pre-existing intentional behavior. Verdict: Approve with minor suggestion - add CHANGELOG entry for the breaking AioSource::register trait signature change.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tokio/tests/io_async_fd.rs (1)

103-119: ⚠️ Potential issue | 🟡 Minor

Fix panic labels in set_nonblocking to match the actual fcntl ops.

The expect(...) messages reference F_GETFD / F_SETFD, but the code calls F_GETFL / F_SETFL, which makes failure diagnostics misleading.

Suggested patch
-    let flags = nix::fcntl::fcntl(fd, F_GETFL).expect("fcntl(F_GETFD)");
+    let flags = nix::fcntl::fcntl(fd, F_GETFL).expect("fcntl(F_GETFL)");
@@
-    nix::fcntl::fcntl(fd, F_SETFL(flags)).expect("fcntl(F_SETFD)");
+    nix::fcntl::fcntl(fd, F_SETFL(flags)).expect("fcntl(F_SETFL)");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tokio/tests/io_async_fd.rs` around lines 103 - 119, The panic messages in
set_nonblocking refer to the wrong fcntl operations (they mention F_GETFD /
F_SETFD) which is misleading; update the expect/panic strings to reference the
actual ops used (F_GETFL and F_SETFL) and ensure the error context matches the
calls to nix::fcntl::fcntl(fd, F_GETFL) and nix::fcntl::fcntl(fd,
F_SETFL(flags)); adjust both the initial expect("fcntl(F_GETFD)") and the final
expect("fcntl(F_SETFD)") to accurate messages like "fcntl(F_GETFL)" and
"fcntl(F_SETFL)" (or similar descriptive text) so failures in set_nonblocking
point to the correct syscall.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tokio/src/io/bsd/poll_aio.rs`:
- Around line 19-22: The change to AioSource::register to take BorrowedFd<'_>
breaks existing implementers; restore a non-breaking API by reintroducing the
original signature register(&mut self, fd: RawFd, token: usize) (or provide a
default method with that signature) and implement a small wrapper that converts
the RawFd into a BorrowedFd and calls the new BorrowedFd-based implementation
(or vice versa) so existing impls compile; update the trait to include both
signatures (one delegating to the other) and ensure the public trait symbol
AioSource::register remains usable by downstream code.

---

Outside diff comments:
In `@tokio/tests/io_async_fd.rs`:
- Around line 103-119: The panic messages in set_nonblocking refer to the wrong
fcntl operations (they mention F_GETFD / F_SETFD) which is misleading; update
the expect/panic strings to reference the actual ops used (F_GETFL and F_SETFL)
and ensure the error context matches the calls to nix::fcntl::fcntl(fd, F_GETFL)
and nix::fcntl::fcntl(fd, F_SETFL(flags)); adjust both the initial
expect("fcntl(F_GETFD)") and the final expect("fcntl(F_SETFD)") to accurate
messages like "fcntl(F_GETFL)" and "fcntl(F_SETFL)" (or similar descriptive
text) so failures in set_nonblocking point to the correct syscall.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eb34b1f3-1f6c-4296-8815-4b7d1be58da6

📥 Commits

Reviewing files that changed from the base of the PR and between 0f7ef49 and ca7d441.

📒 Files selected for processing (6)
  • tokio/Cargo.toml
  • tokio/src/io/bsd/poll_aio.rs
  • tokio/tests/io_async_fd.rs
  • tokio/tests/io_async_fd_memory_leak.rs
  • tokio/tests/io_poll_aio.rs
  • tokio/tests/net_unix_pipe.rs

Comment on lines 19 to 22
pub trait AioSource {
/// Registers this AIO event source with Tokio's reactor.
fn register(&mut self, kq: RawFd, token: usize);
fn register(&mut self, kq: BorrowedFd<'_>, token: usize);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

This is a public API break for AioSource implementers.

Changing register from raw-fd-style input to BorrowedFd<'_> will break downstream impls at compile time. If intentional, this should be treated as a breaking-change path (or have a compatibility strategy / explicit release-note callout).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tokio/src/io/bsd/poll_aio.rs` around lines 19 - 22, The change to
AioSource::register to take BorrowedFd<'_> breaks existing implementers; restore
a non-breaking API by reintroducing the original signature register(&mut self,
fd: RawFd, token: usize) (or provide a default method with that signature) and
implement a small wrapper that converts the RawFd into a BorrowedFd and calls
the new BorrowedFd-based implementation (or vice versa) so existing impls
compile; update the trait to include both signatures (one delegating to the
other) and ensure the public trait symbol AioSource::register remains usable by
downstream code.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value:useful; category:bug; feedback: The CodeRabbit AI reviewer is correct! The signature change is an API breakage and it cannot be made. A new method will need to be added to the trait with a default implementation, so that it does not break the implementers .

@augmentcode
Copy link
Copy Markdown

augmentcode bot commented Mar 29, 2026

🤖 Augment PR Summary

Summary: Make FreeBSD POSIX AIO integration use IO-safe file descriptor types.

Changes:

  • Bump mio to 1.2 and update related dev-deps (nix 0.31, mio-aio 2).
  • Switch AioSource::register from RawFd to BorrowedFd and use Registry::as_fd().
  • Update AIO/AsyncFd tests to pass OwnedFd/AsFd into nix APIs instead of raw fds.

    Why: Reduce raw-fd exposure and align with newer mio/Rust IO-safety interfaces.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

pub trait AioSource {
/// Registers this AIO event source with Tokio's reactor.
fn register(&mut self, kq: RawFd, token: usize);
fn register(&mut self, kq: BorrowedFd<'_>, token: usize);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tokio::io::bsd::AioSource is publicly re-exported, so changing register from RawFd to BorrowedFd is a breaking API change for FreeBSD users; can you confirm this is acceptable for the release/changelog you’re targeting?

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value:useful; category:bug; feedback: The Augment AI reviewer is correct! The signature change is an API breakage and it cannot be made. A new method will need to be added to the trait with a default implementation, so that it does not break the existing implementations .

# Everything else is optional...
bytes = { version = "1.2.1", optional = true }
mio = { version = "1.0.1", optional = true, default-features = false }
mio = { version = "1.2.0", optional = true, default-features = false }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These dependency bumps (mio/nix/mio-aio) could implicitly raise the effective MSRV above rust-version = "1.71"; consider ensuring CI still exercises/builds on 1.71 so this doesn’t regress older toolchains.

Severity: medium

Other Locations
  • tokio/Cargo.toml:115
  • tokio/Cargo.toml:125
  • tokio/Cargo.toml:160

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value:good-to-have; category:bug; feedback: The Augment AI reviewer is correct! The Minimum Supported Rust Version (MSRV) could change while updating dependencies. The Tokio project has a CI job that checks the build with 1.71, so such problems would be caught early!

@martin-augment
Copy link
Copy Markdown
Owner Author

(4) Breaking API change: AioSource::register signature change from RawFd to BorrowedFd is breaking for downstream implementors - even though FreeBSD-only and behind tokio_unstable, should be documented in CHANGELOG.

value:useful; category:bug; feedback: The Claude AI reviewer is correct! The signature change is an API breakage and it cannot be made. A new method will need to be added to the trait with a default implementation, so that it does not break the implementers .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants