use std::io;
use std::time::Duration;
use super::Builder;
const SEND_FILE_CHUNK_MAX: usize = 0x7fff_f000;
#[derive(Clone, Copy, Debug)]
pub(crate) struct IoKnobs {
pub(crate) linger: Duration,
pub(crate) send_file_chunk: u64,
}
impl Default for IoKnobs {
fn default() -> Self {
Self {
linger: crate::io::handle::LINGER,
send_file_chunk: crate::net::send_file::SEND_FILE_CHUNK,
}
}
}
#[derive(Clone, Copy, Debug, Default)]
pub(super) struct IoSettings {
linger: Option<Duration>,
send_file_chunk: Option<usize>,
}
impl IoSettings {
pub(super) fn validate(&self) -> io::Result<()> {
use crate::config::refuse;
if let Some(linger) = self.linger.filter(|l| l.is_zero()) {
return Err(refuse(
"write_behind_linger",
format_args!("{linger:?}"),
"more than zero",
));
}
if let Some(bytes) = self
.send_file_chunk
.filter(|&b| !(1..=SEND_FILE_CHUNK_MAX).contains(&b))
{
return Err(refuse(
"send_file_chunk",
bytes,
format_args!("from 1 to {SEND_FILE_CHUNK_MAX} bytes"),
));
}
Ok(())
}
pub(super) fn resolve(self) -> IoKnobs {
let default = IoKnobs::default();
IoKnobs {
linger: self.linger.unwrap_or(default.linger),
send_file_chunk: self
.send_file_chunk
.map_or(default.send_file_chunk, |b| b as u64),
}
}
}
impl Builder {
pub fn write_behind_linger(mut self, linger: Duration) -> Self {
self.io.linger = Some(linger);
self
}
#[cfg_attr(not(ring), expect(unused_mut, reason = "only a ring sends zero-copy"))]
pub fn zero_copy_threshold(mut self, bytes: usize) -> Self {
#[cfg(ring)]
{
self.tuning.zero_copy_min = bytes;
}
#[cfg(not(ring))]
let _ = bytes;
self
}
pub fn send_file_chunk(mut self, bytes: usize) -> Self {
self.io.send_file_chunk = Some(bytes);
self
}
}
pub(crate) fn current() -> IoKnobs {
super::running_inner().map_or_else(IoKnobs::default, |inner| inner.io)
}
#[cfg(test)]
mod tests;