asterinas/services/aster-nix/src/net/iface/util.rs

77 lines
2.0 KiB
Rust

// SPDX-License-Identifier: MPL-2.0
use aster_frame::timer::read_monotonic_milli_seconds;
use crate::{
prelude::*,
thread::{
kernel_thread::{KernelThreadExt, ThreadOptions},
Thread,
},
};
use super::Iface;
pub enum BindPortConfig {
CanReuse(u16),
Specified(u16),
Ephemeral,
}
impl BindPortConfig {
pub fn new(port: u16, can_reuse: bool) -> Result<Self> {
let config = if port != 0 {
if can_reuse {
Self::CanReuse(port)
} else {
Self::Specified(port)
}
} else if can_reuse {
return_errno_with_message!(Errno::EINVAL, "invalid bind port config");
} else {
Self::Ephemeral
};
Ok(config)
}
pub(super) fn can_reuse(&self) -> bool {
matches!(self, Self::CanReuse(_))
}
pub(super) fn port(&self) -> Option<u16> {
match self {
Self::CanReuse(port) | Self::Specified(port) => Some(*port),
Self::Ephemeral => None,
}
}
}
pub fn spawn_background_poll_thread(iface: Arc<dyn Iface>) {
// FIXME: use timer or wait_timeout when timer is enable.
let task_fn = move || {
debug!("spawn background poll thread");
loop {
let next_poll_time = if let Some(next_poll_time) = iface.next_poll_at_ms() {
next_poll_time
} else {
Thread::yield_now();
continue;
};
let now = read_monotonic_milli_seconds();
if now > next_poll_time {
// FIXME: now is later than next poll time. This may cause problem.
iface.poll();
continue;
}
let duration = next_poll_time - now;
// FIXME: choose a suitable time interval
if duration < 10 {
iface.poll();
} else {
Thread::yield_now();
}
}
};
Thread::spawn_kernel_thread(ThreadOptions::new(task_fn));
}