fix(player): stop engine before dropping ALSA stream on format change
In the Play and PlayStreaming handlers, the old engine's writer thread still holds an Arc<AlsaDirectStream> when the stream_opt is dropped and a new snd_pcm_open() is attempted. This causes EBUSY on track switches with sample rate changes. Reorder to: stop engine -> drop stream -> open new stream, matching the Stop handler's correct lifecycle. cc
This commit is contained in:
1 file changed
+22
-1
@@ -1145,8 +1145,18 @@ impl Player {
|
||||
} else {
|
||||
log::info!("Creating initial audio stream");
|
||||
}
|
||||
// Drop old stream
|
||||
// Stop engine FIRST so its writer thread releases its
|
||||
// Arc<AlsaDirectStream> reference before we drop the stream.
|
||||
// Without this, snd_pcm_open() races against the old PCM
|
||||
// handle and fails with EBUSY.
|
||||
if let Some(engine) = current_engine.take() {
|
||||
engine.stop();
|
||||
std::thread::sleep(Duration::from_millis(50));
|
||||
}
|
||||
// Now this drop is the last Arc ref — PCM actually closes
|
||||
drop(stream_opt.take());
|
||||
// Give kernel time to fully release the ALSA device
|
||||
std::thread::sleep(Duration::from_millis(50));
|
||||
}
|
||||
|
||||
log::info!(
|
||||
@@ -1585,7 +1595,18 @@ impl Player {
|
||||
mode
|
||||
);
|
||||
}
|
||||
// Stop engine FIRST so its writer thread releases its
|
||||
// Arc<AlsaDirectStream> reference before we drop the stream.
|
||||
// Without this, snd_pcm_open() races against the old PCM
|
||||
// handle and fails with EBUSY.
|
||||
if let Some(engine) = current_engine.take() {
|
||||
engine.stop();
|
||||
std::thread::sleep(Duration::from_millis(50));
|
||||
}
|
||||
// Now this drop is the last Arc ref — PCM actually closes
|
||||
drop(stream_opt.take());
|
||||
// Give kernel time to fully release the ALSA device
|
||||
std::thread::sleep(Duration::from_millis(50));
|
||||
}
|
||||
|
||||
let stream_result = if let Some(settings) =
|
||||
|
||||
Reference in new issue
Block a user