Input & Driver: Fix zombie processes on Unix (#39)

Linux/Unix requires that processes be waited, which is unfortunate as Windows lets us abandon them to the murderous whims of the OS. This PR adds Unix-specific behaviour to send a SIGINT before waiting on the process, and adds an additional thread per call for asset disposal on all platforms.

Closes #38.

---

* Close processes by SIGINT and wait on Unix

This seems to remedy the Linux-specific zombie processes. Addition of
nix as a dependency *should* be fine on Windows, since I believe it
compiles to an empty crate.

* Dispose of Tracks on auxiliary thread

This adds a mechanism for the mixer threads to perform potentially expensive deallocation/cleanup outside of the main loop, preventing deadline misses etc. This should make misbehaving `wait`s a bit more friendly.
This commit is contained in:
Kyle Simpson
2021-01-26 20:19:51 +00:00
committed by GitHub
parent a0e905a83f
commit fe2282cfde
7 changed files with 64 additions and 4 deletions

View File

@@ -5,6 +5,12 @@ use std::{
};
use tracing::debug;
#[cfg(unix)]
use nix::{
sys::signal::{self, Signal},
unistd::Pid,
};
/// Handle for a child process which ensures that any subprocesses are properly closed
/// on drop.
#[derive(Debug)]
@@ -31,7 +37,18 @@ impl Read for ChildContainer {
impl Drop for ChildContainer {
fn drop(&mut self) {
if let Err(e) = self.0.kill() {
#[cfg(not(unix))]
let attempt = self.0.kill();
#[cfg(unix)]
let attempt = {
let pid = Pid::from_raw(self.0.id() as i32);
let _ = signal::kill(pid, Signal::SIGINT);
self.0.wait()
};
if let Err(e) = attempt {
debug!("Error awaiting child process: {:?}", e);
}
}