diff options
| author | David Carlier <devnexen@gmail.com> | 2024-01-05 21:22:42 +0000 |
|---|---|---|
| committer | David Carlier <devnexen@gmail.com> | 2024-02-21 20:59:15 +0000 |
| commit | 85bf4439e614f2971523e380b69bb3be4c995894 (patch) | |
| tree | fb334fd9cd79fc481ceaa16bc1eef632a7692b1b /library/std/src/os/net/linux_ext | |
| parent | f8131a48a46ac3bc8a3d0fe0477055b132cffdc3 (diff) | |
os::net: expanding TcpStreamExt for Linux with `tcp_deferaccept`.
allows for socket to process only when there is data to process, the option sets a number of seconds until the data is ready.
Diffstat (limited to 'library/std/src/os/net/linux_ext')
| -rw-r--r-- | library/std/src/os/net/linux_ext/tcp.rs | 55 | ||||
| -rw-r--r-- | library/std/src/os/net/linux_ext/tests.rs | 26 |
2 files changed, 81 insertions, 0 deletions
diff --git a/library/std/src/os/net/linux_ext/tcp.rs b/library/std/src/os/net/linux_ext/tcp.rs index 5e9ee65a415..ff29afe7ed3 100644 --- a/library/std/src/os/net/linux_ext/tcp.rs +++ b/library/std/src/os/net/linux_ext/tcp.rs @@ -53,6 +53,51 @@ pub trait TcpStreamExt: Sealed { /// ``` #[unstable(feature = "tcp_quickack", issue = "96256")] fn quickack(&self) -> io::Result<bool>; + + /// A socket listener will be awakened solely when data arrives. + /// + /// The `accept` argument set the delay in seconds until the + /// data is available to read, reducing the number of short lived + /// connections without data to process. + /// Contrary to other platforms `SO_ACCEPTFILTER` feature equivalent, there is + /// no necessity to set it after the `listen` call. + /// + /// See [`man 7 tcp`](https://man7.org/linux/man-pages/man7/tcp.7.html) + /// + /// # Examples + /// + /// ```no run + /// #![feature(tcp_deferaccept)] + /// use std::net::TcpStream; + /// use std::os::linux::net::TcpStreamExt; + /// + /// let stream = TcpStream::connect("127.0.0.1:8080") + /// .expect("Couldn't connect to the server..."); + /// stream.set_deferaccept(1).expect("set_deferaccept call failed"); + /// ``` + #[unstable(feature = "tcp_deferaccept", issue = "119639")] + #[cfg(target_os = "linux")] + fn set_deferaccept(&self, accept: u32) -> io::Result<()>; + + /// Gets the accept delay value (in seconds) of the `TCP_DEFER_ACCEPT` option. + /// + /// For more information about this option, see [`TcpStreamExt::set_deferaccept`]. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(tcp_deferaccept)] + /// use std::net::TcpStream; + /// use std::os::linux::net::TcpStreamExt; + /// + /// let stream = TcpStream::connect("127.0.0.1:8080") + /// .expect("Couldn't connect to the server..."); + /// stream.set_deferaccept(1).expect("set_deferaccept call failed"); + /// assert_eq!(stream.deferaccept().unwrap_or(0), 1); + /// ``` + #[unstable(feature = "tcp_deferaccept", issue = "119639")] + #[cfg(target_os = "linux")] + fn deferaccept(&self) -> io::Result<u32>; } #[unstable(feature = "tcp_quickack", issue = "96256")] @@ -67,4 +112,14 @@ impl TcpStreamExt for net::TcpStream { fn quickack(&self) -> io::Result<bool> { self.as_inner().as_inner().quickack() } + + #[cfg(target_os = "linux")] + fn set_deferaccept(&self, accept: u32) -> io::Result<()> { + self.as_inner().as_inner().set_deferaccept(accept) + } + + #[cfg(target_os = "linux")] + fn deferaccept(&self) -> io::Result<u32> { + self.as_inner().as_inner().deferaccept() + } } diff --git a/library/std/src/os/net/linux_ext/tests.rs b/library/std/src/os/net/linux_ext/tests.rs index 2db4deed036..f8dbbfc18e2 100644 --- a/library/std/src/os/net/linux_ext/tests.rs +++ b/library/std/src/os/net/linux_ext/tests.rs @@ -26,3 +26,29 @@ fn quickack() { t!(stream.set_quickack(false)); assert_eq!(false, t!(stream.quickack())); } + +#[test] +#[cfg(target_os = "linux")] +fn deferaccept() { + use crate::{ + net::{test::next_test_ip4, TcpListener, TcpStream}, + os::net::linux_ext::tcp::TcpStreamExt, + }; + + macro_rules! t { + ($e:expr) => { + match $e { + Ok(t) => t, + Err(e) => panic!("received error for `{}`: {}", stringify!($e), e), + } + }; + } + + let addr = next_test_ip4(); + let _listener = t!(TcpListener::bind(&addr)); + let stream = t!(TcpStream::connect(&("localhost", addr.port()))); + stream.set_deferaccept(1).expect("set_deferaccept failed"); + assert_eq!(stream.deferaccept().unwrap(), 1); + stream.set_deferaccept(0).expect("set_deferaccept failed"); + assert_eq!(stream.deferaccept().unwrap(), 0); +} |
