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:
@@ -1,4 +1,4 @@
|
||||
use super::{error::Result, message::*, Config};
|
||||
use super::{disposal, error::Result, message::*, Config};
|
||||
use crate::{
|
||||
constants::*,
|
||||
tracks::{PlayMode, Track},
|
||||
@@ -28,6 +28,7 @@ pub struct Mixer {
|
||||
pub config: Config,
|
||||
pub conn_active: Option<MixerConnection>,
|
||||
pub deadline: Instant,
|
||||
pub disposer: Sender<DisposalMessage>,
|
||||
pub encoder: OpusEncoder,
|
||||
pub interconnect: Interconnect,
|
||||
pub mix_rx: Receiver<MixerMessage>,
|
||||
@@ -74,12 +75,17 @@ impl Mixer {
|
||||
|
||||
let tracks = Vec::with_capacity(1.max(config.preallocated_tracks));
|
||||
|
||||
// Create an object disposal thread here.
|
||||
let (disposer, disposal_rx) = flume::unbounded();
|
||||
std::thread::spawn(move || disposal::runner(disposal_rx));
|
||||
|
||||
Self {
|
||||
async_handle,
|
||||
bitrate,
|
||||
config,
|
||||
conn_active: None,
|
||||
deadline: Instant::now(),
|
||||
disposer,
|
||||
encoder,
|
||||
interconnect,
|
||||
mix_rx,
|
||||
@@ -322,12 +328,13 @@ impl Mixer {
|
||||
|
||||
if track.playing.is_done() {
|
||||
let p_state = track.playing();
|
||||
self.tracks.swap_remove(i);
|
||||
let to_drop = self.tracks.swap_remove(i);
|
||||
to_remove.push(i);
|
||||
self.fire_event(EventMessage::ChangeState(
|
||||
i,
|
||||
TrackStateChange::Mode(p_state),
|
||||
))?;
|
||||
let _ = self.disposer.send(DisposalMessage::Track(to_drop));
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
@@ -580,4 +587,6 @@ pub(crate) fn runner(
|
||||
let mut mixer = Mixer::new(mix_rx, async_handle, interconnect, config);
|
||||
|
||||
mixer.run();
|
||||
|
||||
let _ = mixer.disposer.send(DisposalMessage::Poison);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user