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 {
|
} else {
|
||||||
log::info!("Creating initial audio stream");
|
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());
|
drop(stream_opt.take());
|
||||||
|
// Give kernel time to fully release the ALSA device
|
||||||
|
std::thread::sleep(Duration::from_millis(50));
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
@@ -1585,7 +1595,18 @@ impl Player {
|
|||||||
mode
|
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());
|
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) =
|
let stream_result = if let Some(settings) =
|
||||||
|
|||||||
Reference in new issue
Block a user