use { parking_lot::{Condvar, Mutex}, std::{mem, rc::Rc, sync::Arc}, uapi::OwnedFd, }; pub struct FdCloser { fds: Mutex>, cv: Condvar, } impl FdCloser { pub fn new() -> Arc { let slf = Arc::new(Self { fds: Mutex::new(Vec::new()), cv: Condvar::new(), }); let slf2 = slf.clone(); std::thread::Builder::new() .name("fd closer".to_string()) .spawn(move || { let mut fds = vec![]; let mut lock = slf2.fds.lock(); loop { mem::swap(&mut *lock, &mut fds); if fds.len() > 0 { drop(lock); fds.clear(); lock = slf2.fds.lock(); } else { slf2.cv.wait(&mut lock); } } }) .unwrap(); slf } pub fn close(&self, fd: Rc) { match Rc::try_unwrap(fd) { Ok(fd) => { self.fds.lock().push(fd); self.cv.notify_all(); } Err(_e) => { log::warn!( "Could not close file descriptor in separate thread. There are still references." ); } } } }