aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-08-08 15:57:06 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-08-08 15:57:06 +0100
commit4977bb09ddb7dc97d8452fb1021af14b9695f627 (patch)
treea9a46ccf321af3256a855dcfca28637c786f04e7
parentb8dc0fcff10702ab38db2d318f8fa2b8fc5c61b0 (diff)
parenta384c205acaa4b6fe6d4d392af47b49b2c448eb4 (diff)
Merge remote-tracking branch 'remotes/armbru/tags/pull-monitor-2016-08-08' into staging
Monitor patches for 2016-08-08 # gpg: Signature made Mon 08 Aug 2016 13:24:42 BST # gpg: using RSA key 0x3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-monitor-2016-08-08: audio: clean up before monitor clean up monitor: fix crash when leaving qemu with spice audio Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--audio/audio.c26
-rw-r--r--audio/audio.h3
-rw-r--r--audio/coreaudio.c12
-rw-r--r--include/monitor/monitor.h1
-rw-r--r--monitor.c20
-rw-r--r--vl.c2
6 files changed, 46 insertions, 18 deletions
diff --git a/audio/audio.c b/audio/audio.c
index 9d4dcc72dd..c845a44f0a 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -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;
diff --git a/audio/audio.h b/audio/audio.h
index 11e56c9d17..c3c51988f5 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -163,4 +163,7 @@ static inline void *advance (void *p, int incr)
int wav_start_capture (CaptureState *s, const char *path, int freq,
int bits, int nchannels);
+bool audio_is_cleaning_up(void);
+void audio_cleanup(void);
+
#endif /* QEMU_AUDIO_H */
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index d4ad224590..c75142084f 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -36,8 +36,6 @@
#define MAC_OS_X_VERSION_10_6 1060
#endif
-static int isAtexit;
-
typedef struct {
int buffer_frames;
int nbuffers;
@@ -378,11 +376,6 @@ static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
return result;
}
-static void coreaudio_atexit (void)
-{
- isAtexit = 1;
-}
-
static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
{
int err;
@@ -630,7 +623,7 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
int err;
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
- if (!isAtexit) {
+ if (!audio_is_cleaning_up()) {
/* stop playback */
if (isPlaying(core->outputDeviceID)) {
status = AudioDeviceStop(core->outputDeviceID, core->ioprocid);
@@ -673,7 +666,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
case VOICE_DISABLE:
/* stop playback */
- if (!isAtexit) {
+ if (!audio_is_cleaning_up()) {
if (isPlaying(core->outputDeviceID)) {
status = AudioDeviceStop(core->outputDeviceID,
core->ioprocid);
@@ -697,7 +690,6 @@ static void *coreaudio_audio_init (void)
CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf));
*conf = glob_conf;
- atexit(coreaudio_atexit);
return conf;
}
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index c5c9ea292f..a714d8ef80 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -17,6 +17,7 @@ extern Monitor *cur_mon;
bool monitor_cur_is_qmp(void);
void monitor_init(CharDriverState *chr, int flags);
+void monitor_cleanup(void);
int monitor_suspend(Monitor *mon);
void monitor_resume(Monitor *mon);
diff --git a/monitor.c b/monitor.c
index 5d68a5d6fc..5c003731e2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -635,6 +635,13 @@ static void monitor_data_init(Monitor *mon)
static void monitor_data_destroy(Monitor *mon)
{
+ if (mon->chr) {
+ qemu_chr_add_handlers(mon->chr, NULL, NULL, NULL, NULL);
+ }
+ if (monitor_is_qmp(mon)) {
+ json_message_parser_destroy(&mon->qmp.parser);
+ }
+ g_free(mon->rs);
QDECREF(mon->outbuf);
qemu_mutex_destroy(&mon->out_lock);
}
@@ -4196,6 +4203,19 @@ void monitor_init(CharDriverState *chr, int flags)
qemu_mutex_unlock(&monitor_lock);
}
+void monitor_cleanup(void)
+{
+ Monitor *mon, *next;
+
+ qemu_mutex_lock(&monitor_lock);
+ QLIST_FOREACH_SAFE(mon, &mon_list, entry, next) {
+ QLIST_REMOVE(mon, entry);
+ monitor_data_destroy(mon);
+ g_free(mon);
+ }
+ qemu_mutex_unlock(&monitor_lock);
+}
+
static void bdrv_password_cb(void *opaque, const char *password,
void *readline_opaque)
{
diff --git a/vl.c b/vl.c
index e7c2c628de..c4eeaffb91 100644
--- a/vl.c
+++ b/vl.c
@@ -4612,6 +4612,8 @@ int main(int argc, char **argv, char **envp)
/* vhost-user must be cleaned up before chardevs. */
net_cleanup();
+ audio_cleanup();
+ monitor_cleanup();
qemu_chr_cleanup();
return 0;