Skip to content

Add simple interface for busy_poll on Linux #607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 23, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
15 changes: 15 additions & 0 deletions src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,21 @@ impl Socket {
sys::set_nonblocking(self.as_raw(), nonblocking)
}

/// Sets the busy polling timeout in microseconds for blocking socket operations.
///
/// When there is no data available, the socket will busy poll for the specified
/// duration (in microseconds) before falling back to blocking behavior.
///
/// # Notes
///
/// - Requires `CAP_NET_ADMIN` capability to increase the value
/// - Default value is controlled by `/proc/sys/net/core/busy_read`
/// - Available since Linux 3.11
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we replace these notes with only calling out SO_BUSY_POLL, similar to the other functions. I don't want to copy all notes from the man page.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, if it's your wish.

#[cfg(target_os = "linux")]
Copy link
Collaborator

Choose a reason for hiding this comment

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

This needs to be behind the all feature, see other functions that have limited cross-OS availability.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not familiar with all the targets, but I'll try?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I manually searched and used the API and found that none of the targets listed in the README support busy polling. Here is the link to the documentation I found manually. So, I guess there is nothing else.

Apple
Windows
android
FreeBSD
Fuchsia
illumos
NetBSD
Redox
Solaris
OpenHarmony

I found a great list btw: https://docs.rs/rustix/latest/rustix/net/sockopt/index.html

pub fn set_busy_poll(&self, busy_poll: u16) -> io::Result<()> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why u16?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, this is my question. When I saw that most C code used int, I was confused why it was not unsigned int. I thought this type problem should be corrected, so I filled in u16. Now I will change it to u32 next time.

sys::set_busy_poll(self.as_raw(), busy_poll)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we have a getting for this as well?

Copy link
Contributor Author

@nan-mu nan-mu Jul 22, 2025

Choose a reason for hiding this comment

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

Well, if you could specify I'd appreciate it, basically I copied the code from set_nonblocking.

Oh, set_mark is that one, that makes things easier.


/// Shuts down the read, write, or both halves of this connection.
///
/// This function will cause all pending and future I/O on the specified
Expand Down
5 changes: 5 additions & 0 deletions src/sys/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,11 @@ pub(crate) fn set_nonblocking(fd: RawSocket, nonblocking: bool) -> io::Result<()
}
}

#[cfg(target_os = "linux")]
pub(crate) fn set_busy_poll(fd: RawSocket, busy_poll: u16) -> io::Result<()> {
unsafe { setsockopt(fd, libc::SOL_SOCKET, libc::SO_BUSY_POLL, busy_poll as c_int) }
}

pub(crate) fn shutdown(fd: RawSocket, how: Shutdown) -> io::Result<()> {
let how = match how {
Shutdown::Write => libc::SHUT_WR,
Expand Down
Loading