Skip to content

Commit

Permalink
Fix infinite loop on broken ALSA pipes (#934)
Browse files Browse the repository at this point in the history
  • Loading branch information
cdellacqua authored Jan 12, 2025
1 parent c11571b commit 4a8c9b8
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/host/alsa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
SupportedBufferSize, SupportedStreamConfig, SupportedStreamConfigRange,
SupportedStreamConfigsError,
};
use std::cell::Cell;
use std::cmp;
use std::convert::TryInto;
use std::sync::{Arc, Mutex};
Expand Down Expand Up @@ -286,6 +287,7 @@ impl Device {
}

let stream_inner = StreamInner {
dropping: Cell::new(false),
channel: handle,
sample_format,
num_descriptors,
Expand Down Expand Up @@ -501,6 +503,10 @@ impl Device {
}

struct StreamInner {
// Flag used to check when to stop polling, regardless of the state of the stream
// (e.g. broken due to a disconnected device).
dropping: Cell<bool>,

// The ALSA channel.
channel: alsa::pcm::PCM,

Expand Down Expand Up @@ -696,6 +702,12 @@ fn poll_descriptors_and_prepare_buffer(
stream: &StreamInner,
ctxt: &mut StreamWorkerContext,
) -> Result<PollDescriptorsFlow, BackendSpecificError> {
if stream.dropping.get() {
// The stream has been requested to be destroyed.
rx.clear_pipe();
return Ok(PollDescriptorsFlow::Return);
}

let StreamWorkerContext {
ref mut descriptors,
ref mut buffer,
Expand Down Expand Up @@ -982,6 +994,7 @@ impl Stream {

impl Drop for Stream {
fn drop(&mut self) {
self.inner.dropping.set(true);
self.trigger.wakeup();
self.thread.take().unwrap().join().unwrap();
}
Expand Down

0 comments on commit 4a8c9b8

Please sign in to comment.