Skip to content

Commit 02b454c

Browse files
authored
Fix callback being called after dropping the stream (#869)
* Fix callback being called after dropping the stream * Use weak reference to stream in disconnect listener
1 parent d7dee9a commit 02b454c

File tree

1 file changed

+34
-22
lines changed
  • src/host/coreaudio/macos

1 file changed

+34
-22
lines changed

src/host/coreaudio/macos/mod.rs

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,32 @@ struct StreamInner {
442442
device_id: AudioDeviceID,
443443
}
444444

445+
impl StreamInner {
446+
fn play(&mut self) -> Result<(), PlayStreamError> {
447+
if !self.playing {
448+
if let Err(e) = self.audio_unit.start() {
449+
let description = format!("{}", e);
450+
let err = BackendSpecificError { description };
451+
return Err(err.into());
452+
}
453+
self.playing = true;
454+
}
455+
Ok(())
456+
}
457+
458+
fn pause(&mut self) -> Result<(), PauseStreamError> {
459+
if self.playing {
460+
if let Err(e) = self.audio_unit.stop() {
461+
let description = format!("{}", e);
462+
let err = BackendSpecificError { description };
463+
return Err(err.into());
464+
}
465+
self.playing = false;
466+
}
467+
Ok(())
468+
}
469+
}
470+
445471
/// Register the on-disconnect callback.
446472
/// This will both stop the stream and call the error callback with DeviceNotAvailable.
447473
/// This function should only be called once per stream.
@@ -452,7 +478,7 @@ fn add_disconnect_listener<E>(
452478
where
453479
E: FnMut(StreamError) + Send + 'static,
454480
{
455-
let stream_copy = stream.clone();
481+
let stream_inner_weak = Arc::downgrade(&stream.inner);
456482
let mut stream_inner = stream.inner.lock().unwrap();
457483
stream_inner._disconnect_listener = Some(AudioObjectPropertyListener::new(
458484
stream_inner.device_id,
@@ -462,8 +488,11 @@ where
462488
mElement: kAudioObjectPropertyElementMaster,
463489
},
464490
move || {
465-
let _ = stream_copy.pause();
466-
(error_callback.lock().unwrap())(StreamError::DeviceNotAvailable);
491+
if let Some(stream_inner_strong) = stream_inner_weak.upgrade() {
492+
let mut stream_inner = stream_inner_strong.lock().unwrap();
493+
let _ = stream_inner.pause();
494+
(error_callback.lock().unwrap())(StreamError::DeviceNotAvailable);
495+
}
467496
},
468497
)?);
469498
Ok(())
@@ -897,30 +926,13 @@ impl StreamTrait for Stream {
897926
fn play(&self) -> Result<(), PlayStreamError> {
898927
let mut stream = self.inner.lock().unwrap();
899928

900-
if !stream.playing {
901-
if let Err(e) = stream.audio_unit.start() {
902-
let description = format!("{}", e);
903-
let err = BackendSpecificError { description };
904-
return Err(err.into());
905-
}
906-
stream.playing = true;
907-
}
908-
Ok(())
929+
stream.play()
909930
}
910931

911932
fn pause(&self) -> Result<(), PauseStreamError> {
912933
let mut stream = self.inner.lock().unwrap();
913934

914-
if stream.playing {
915-
if let Err(e) = stream.audio_unit.stop() {
916-
let description = format!("{}", e);
917-
let err = BackendSpecificError { description };
918-
return Err(err.into());
919-
}
920-
921-
stream.playing = false;
922-
}
923-
Ok(())
935+
stream.pause()
924936
}
925937
}
926938

0 commit comments

Comments
 (0)