12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- use nix::sys::wait::{WaitPidFlag, WaitStatus};
- use tokio::signal::unix::{signal, SignalKind, Signal};
- use crate::logger::LogWriter;
- use std::sync::atomic::{AtomicU64, Ordering};
- use lazy_static::lazy_static;
- lazy_static!{
- static ref REAP_COUNTER: AtomicU64 = AtomicU64::new(0);
- }
- pub struct Reaper {
- sig_stream: Signal,
- logger: LogWriter,
- }
- impl Reaper {
- pub fn new(logger: LogWriter) -> Result<Self, std::io::Error> {
- let stream = signal(SignalKind::child())?;
- Ok(Reaper { sig_stream: stream, logger })
- }
- pub async fn reap(&mut self) -> ! {
- loop {
- self.sig_stream.recv().await;
- loop {
- let wstat = nix::sys::wait::waitpid(nix::unistd::Pid::from_raw(-1), Some(WaitPidFlag::WNOHANG));
- match wstat {
- Ok(ws) => {
- if LogWriter::is_debug_mode() {
- let msg = match ws {
- WaitStatus::Exited(pid, ec) => {
- Some(format!("{}: WIFEXITED ExitCode={}", pid, ec))
- }
- WaitStatus::Signaled(pid, sig, t) => {
- Some(format!("{}: WIFSIGNALED Signal={}, IsCoreDump={}", pid, sig, t))
- }
- WaitStatus::Stopped(pid, c) => {
- Some(format!("{}: WIFSTOPPED Code={}", pid, c))
- }
- WaitStatus::PtraceEvent(pid, sig, c) => {
- Some(format!("{}: PTRACE_EVENT Signal={}, Value={}", pid, sig, c))
- }
- WaitStatus::PtraceSyscall(pid) => {
- Some(format!("{}: PTRACE_SYSCALL", pid))
- }
- WaitStatus::Continued(pid) => {
- Some(format!("{}: WCONTINUED", pid))
- }
- WaitStatus::StillAlive => {
- None
- }
- };
- if let Some(v) = msg {
- REAP_COUNTER.fetch_add(1, Ordering::Relaxed);
- self.logger.error(format!("reap zombie child {}", v).as_str()).await;
- }
- }else{
- if ws != WaitStatus::StillAlive {
- REAP_COUNTER.fetch_add(1, Ordering::Relaxed);
- }
- }
- }
- Err(_) => {}
- };
- }
- };
- }
- }
- pub fn get_count() -> u64 {
- REAP_COUNTER.load(Ordering::Relaxed)
- }
|