|
@@ -1739,13 +1739,21 @@ static void audio_vm_change_state_handler (void *opaque, int running,
|
|
|
audio_reset_timer (s);
|
|
|
}
|
|
|
|
|
|
-static void audio_atexit (void)
|
|
|
+static bool is_cleaning_up;
|
|
|
+
|
|
|
+bool audio_is_cleaning_up(void)
|
|
|
+{
|
|
|
+ return is_cleaning_up;
|
|
|
+}
|
|
|
+
|
|
|
+void audio_cleanup(void)
|
|
|
{
|
|
|
AudioState *s = &glob_audio_state;
|
|
|
- HWVoiceOut *hwo = NULL;
|
|
|
- HWVoiceIn *hwi = NULL;
|
|
|
+ HWVoiceOut *hwo, *hwon;
|
|
|
+ HWVoiceIn *hwi, *hwin;
|
|
|
|
|
|
- while ((hwo = audio_pcm_hw_find_any_out (hwo))) {
|
|
|
+ is_cleaning_up = true;
|
|
|
+ QLIST_FOREACH_SAFE(hwo, &glob_audio_state.hw_head_out, entries, hwon) {
|
|
|
SWVoiceCap *sc;
|
|
|
|
|
|
if (hwo->enabled) {
|
|
@@ -1761,17 +1769,20 @@ static void audio_atexit (void)
|
|
|
cb->ops.destroy (cb->opaque);
|
|
|
}
|
|
|
}
|
|
|
+ QLIST_REMOVE(hwo, entries);
|
|
|
}
|
|
|
|
|
|
- while ((hwi = audio_pcm_hw_find_any_in (hwi))) {
|
|
|
+ QLIST_FOREACH_SAFE(hwi, &glob_audio_state.hw_head_in, entries, hwin) {
|
|
|
if (hwi->enabled) {
|
|
|
hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
|
|
|
}
|
|
|
hwi->pcm_ops->fini_in (hwi);
|
|
|
+ QLIST_REMOVE(hwi, entries);
|
|
|
}
|
|
|
|
|
|
if (s->drv) {
|
|
|
s->drv->fini (s->drv_opaque);
|
|
|
+ s->drv = NULL;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1799,7 +1810,7 @@ static void audio_init (void)
|
|
|
QLIST_INIT (&s->hw_head_out);
|
|
|
QLIST_INIT (&s->hw_head_in);
|
|
|
QLIST_INIT (&s->cap_head);
|
|
|
- atexit (audio_atexit);
|
|
|
+ atexit(audio_cleanup);
|
|
|
|
|
|
s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
|
|
|
|
|
@@ -1966,8 +1977,7 @@ CaptureVoiceOut *AUD_add_capture (
|
|
|
QLIST_INSERT_HEAD (&s->cap_head, cap, entries);
|
|
|
QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
|
|
|
|
|
|
- hw = NULL;
|
|
|
- while ((hw = audio_pcm_hw_find_any_out (hw))) {
|
|
|
+ QLIST_FOREACH(hw, &glob_audio_state.hw_head_out, entries) {
|
|
|
audio_attach_capture (hw);
|
|
|
}
|
|
|
return cap;
|