use procfs::process::Process;
use std::collections::HashMap;
use std::sync::Mutex;
use std::time::{Duration, Instant};
pub fn get_process_name(pid: u32) -> Option<String> {
Process::new(pid as i32)
.ok()
.and_then(|p| p.stat().ok())
.map(|stat| stat.comm)
}
struct ProcessNameCache {
map: HashMap<u32, (String, Instant)>,
}
impl ProcessNameCache {
fn new() -> Self {
Self {
map: HashMap::new(),
}
}
fn get_or_load(&mut self, pid: u32) -> Option<String> {
let now = Instant::now();
self.map.retain(|_, &mut (_, expires)| expires > now);
if let Some((name, _)) = self.map.get(&pid) {
return Some(name.clone());
}
let name = get_process_name(pid)?;
self.map
.insert(pid, (name.clone(), now + Duration::from_secs(5)));
Some(name)
}
}
static PROCESS_NAME_CACHE: std::sync::LazyLock<Mutex<ProcessNameCache>> =
std::sync::LazyLock::new(|| Mutex::new(ProcessNameCache::new()));
pub fn get_process_name_cached(pid: u32) -> Option<String> {
PROCESS_NAME_CACHE.lock().unwrap().get_or_load(pid)
}