@@ -10,6 +10,7 @@ use crate::{
1010 SupportedBufferSize , SupportedStreamConfig , SupportedStreamConfigRange ,
1111 SupportedStreamConfigsError ,
1212} ;
13+ use std:: cell:: Cell ;
1314use std:: cmp;
1415use std:: convert:: TryInto ;
1516use std:: sync:: { Arc , Mutex } ;
@@ -286,6 +287,7 @@ impl Device {
286287 }
287288
288289 let stream_inner = StreamInner {
290+ dropping : Cell :: new ( false ) ,
289291 channel : handle,
290292 sample_format,
291293 num_descriptors,
@@ -501,6 +503,10 @@ impl Device {
501503}
502504
503505struct StreamInner {
506+ // Flag used to check when to stop polling, regardless of the state of the stream
507+ // (e.g. broken due to a disconnected device).
508+ dropping : Cell < bool > ,
509+
504510 // The ALSA channel.
505511 channel : alsa:: pcm:: PCM ,
506512
@@ -696,6 +702,12 @@ fn poll_descriptors_and_prepare_buffer(
696702 stream : & StreamInner ,
697703 ctxt : & mut StreamWorkerContext ,
698704) -> Result < PollDescriptorsFlow , BackendSpecificError > {
705+ if stream. dropping . get ( ) {
706+ // The stream has been requested to be destroyed.
707+ rx. clear_pipe ( ) ;
708+ return Ok ( PollDescriptorsFlow :: Return ) ;
709+ }
710+
699711 let StreamWorkerContext {
700712 ref mut descriptors,
701713 ref mut buffer,
@@ -982,6 +994,7 @@ impl Stream {
982994
983995impl Drop for Stream {
984996 fn drop ( & mut self ) {
997+ self . inner . dropping . set ( true ) ;
985998 self . trigger . wakeup ( ) ;
986999 self . thread . take ( ) . unwrap ( ) . join ( ) . unwrap ( ) ;
9871000 }
0 commit comments