diff --git a/audio/audio_template.h b/audio/audio_template.h index fe769cde66..398a727373 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -172,7 +172,7 @@ static int glue (audio_pcm_sw_init_, TYPE) ( sw->empty = true; #endif - if (audio_format_is_float(hw->info.af)) { + if (audio_format_is_float(sw->info.af)) { #ifdef DAC sw->conv = mixeng_conv_float[sw->info.nchannels == 2] [sw->info.swap_endianness]; @@ -187,9 +187,9 @@ static int glue (audio_pcm_sw_init_, TYPE) ( sw->clip = mixeng_clip #endif [sw->info.nchannels == 2] - [audio_format_is_signed(hw->info.af)] + [audio_format_is_signed(sw->info.af)] [sw->info.swap_endianness] - [audio_format_to_index(hw->info.af)]; + [audio_format_to_index(sw->info.af)]; } sw->name = g_strdup (name); diff --git a/tests/audio/meson.build b/tests/audio/meson.build index 84754bde22..be96313a63 100644 --- a/tests/audio/meson.build +++ b/tests/audio/meson.build @@ -6,12 +6,14 @@ endif modinfo_dep = not_found if enable_modules - modinfo_src = custom_target('modinfo.c', - output: 'modinfo.c', - input: audio_modinfo_files, - command: [modinfo_generate, '--skip-missing-deps', '@INPUT@'], - capture: true) - + modinfo_src = 'modinfo-stub.c' + if audio_modinfo_files.length() != 0 + modinfo_src = custom_target('modinfo.c', + output: 'modinfo.c', + input: audio_modinfo_files, + command: [modinfo_generate, '--skip-missing-deps', '@INPUT@'], + capture: true) + endif modinfo_lib = static_library('modinfo.c', modinfo_src) modinfo_dep = declare_dependency(link_with: modinfo_lib) endif diff --git a/tests/audio/modinfo-stub.c b/tests/audio/modinfo-stub.c new file mode 100644 index 0000000000..1cae8c6905 --- /dev/null +++ b/tests/audio/modinfo-stub.c @@ -0,0 +1,5 @@ +#include "qemu/osdep.h" +#include "qemu/module.h" +const QemuModinfo qemu_modinfo[] = { + { /* end of list */ } +}; diff --git a/ui/dbus-clipboard.c b/ui/dbus-clipboard.c index 6787a77668..935b6b1a2a 100644 --- a/ui/dbus-clipboard.c +++ b/ui/dbus-clipboard.c @@ -191,6 +191,7 @@ static void dbus_clipboard_unregister_proxy(DBusDisplay *dpy) { const char *name = NULL; + GDBusConnection *connection = NULL; int i; for (i = 0; i < G_N_ELEMENTS(dpy->clipboard_request); ++i) { @@ -201,6 +202,13 @@ dbus_clipboard_unregister_proxy(DBusDisplay *dpy) return; } + connection = g_dbus_proxy_get_connection( + G_DBUS_PROXY(dpy->clipboard_proxy)); + if (connection) { + g_signal_handlers_disconnect_by_data(connection, dpy); + } + g_signal_handlers_disconnect_by_data(dpy->clipboard_proxy, dpy); + name = g_dbus_proxy_get_name(G_DBUS_PROXY(dpy->clipboard_proxy)); trace_dbus_clipboard_unregister(name); g_clear_object(&dpy->clipboard_proxy); @@ -425,6 +433,14 @@ dbus_clipboard_request( return DBUS_METHOD_INVOCATION_HANDLED; } +void +dbus_clipboard_fini(DBusDisplay *dpy) +{ + dbus_clipboard_unregister_proxy(dpy); + qemu_clipboard_peer_unregister(&dpy->clipboard_peer); + g_clear_object(&dpy->clipboard); +} + void dbus_clipboard_init(DBusDisplay *dpy) { diff --git a/ui/dbus.c b/ui/dbus.c index 4f24215555..794b65c4ad 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -145,8 +145,7 @@ dbus_display_finalize(Object *o) dbus_display_notifier_remove(&dd->notifier); } - qemu_clipboard_peer_unregister(&dd->clipboard_peer); - g_clear_object(&dd->clipboard); + dbus_clipboard_fini(dd); g_clear_object(&dd->server); g_clear_pointer(&dd->consoles, g_ptr_array_unref); @@ -263,22 +262,52 @@ dbus_display_complete(UserCreatable *uc, Error **errp) } } +typedef struct DBusDisplayAddClientData { + DBusDisplay *display; + GCancellable *cancellable; +} DBusDisplayAddClientData; + +static void dbus_display_add_client_data_free(DBusDisplayAddClientData *data) +{ + if (data->display) { + object_unref(OBJECT(data->display)); + data->display = NULL; + } + g_clear_object(&data->cancellable); + g_free(data); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(DBusDisplayAddClientData, + dbus_display_add_client_data_free) + static void dbus_display_add_client_ready(GObject *source_object, GAsyncResult *res, gpointer user_data) { + g_autoptr(DBusDisplayAddClientData) data = user_data; + DBusDisplay *display = data->display; + bool current = display->add_client_cancellable == data->cancellable; g_autoptr(GError) err = NULL; g_autoptr(GDBusConnection) conn = NULL; - g_clear_object(&dbus_display->add_client_cancellable); + if (current) { + g_clear_object(&display->add_client_cancellable); + } conn = g_dbus_connection_new_finish(res, &err); if (!conn) { - error_printf("Failed to accept D-Bus client: %s", err->message); + if (!g_error_matches(err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + error_printf("Failed to accept D-Bus client: %s", err->message); + } + return; } - g_dbus_object_manager_server_set_connection(dbus_display->server, conn); + if (!current) { + return; + } + + g_dbus_object_manager_server_set_connection(display->server, conn); g_dbus_connection_start_message_processing(conn); } @@ -290,6 +319,7 @@ dbus_display_add_client(int csock, Error **errp) g_autoptr(GSocket) socket = NULL; g_autoptr(GSocketConnection) conn = NULL; g_autofree char *guid = g_dbus_generate_guid(); + DBusDisplayAddClientData *data; if (!dbus_display) { error_setg(errp, "p2p connections not accepted in bus mode"); @@ -298,6 +328,7 @@ dbus_display_add_client(int csock, Error **errp) if (dbus_display->add_client_cancellable) { g_cancellable_cancel(dbus_display->add_client_cancellable); + g_clear_object(&dbus_display->add_client_cancellable); } #ifdef WIN32 @@ -318,6 +349,10 @@ dbus_display_add_client(int csock, Error **errp) conn = g_socket_connection_factory_create_connection(socket); dbus_display->add_client_cancellable = g_cancellable_new(); + data = g_new0(DBusDisplayAddClientData, 1); + data->display = DBUS_DISPLAY(object_ref(OBJECT(dbus_display))); + data->cancellable = g_object_ref(dbus_display->add_client_cancellable); + GDBusConnectionFlags flags = G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER | G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING; @@ -332,7 +367,7 @@ dbus_display_add_client(int csock, Error **errp) NULL, dbus_display->add_client_cancellable, dbus_display_add_client_ready, - NULL); + data); return true; } diff --git a/ui/dbus.h b/ui/dbus.h index 1e8c24a48e..986d777460 100644 --- a/ui/dbus.h +++ b/ui/dbus.h @@ -150,5 +150,6 @@ void dbus_display_notify(DBusDisplayEvent *event); void dbus_chardev_init(DBusDisplay *dpy); void dbus_clipboard_init(DBusDisplay *dpy); +void dbus_clipboard_fini(DBusDisplay *dpy); #endif /* UI_DBUS_H */ diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index b296d19e08..ec90ae6d5f 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -107,11 +107,25 @@ int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h) return 1; } +static void vnc_job_free(VncJob *job) +{ + VncRectEntry *entry, *tmp; + + if (!job) { + return; + } + QLIST_FOREACH_SAFE(entry, &job->rectangles, next, tmp) { + /* no need for QLIST_REMOVE(entry, next) */ + g_free(entry); + } + g_free(job); +} + void vnc_job_push(VncJob *job) { vnc_lock_queue(queue); if (queue->exit || QLIST_EMPTY(&job->rectangles)) { - g_free(job); + vnc_job_free(job); } else { QTAILQ_INSERT_TAIL(&queue->jobs, job, next); qemu_cond_broadcast(&queue->cond); @@ -148,9 +162,7 @@ void vnc_jobs_consume_buffer(VncState *vs) vnc_lock_output(vs); if (vs->jobs_buffer.offset) { if (vs->ioc != NULL && buffer_empty(&vs->output)) { - if (vs->ioc_tag) { - g_source_remove(vs->ioc_tag); - } + g_clear_handle_id(&vs->ioc_tag, g_source_remove); if (vs->disconnecting == FALSE) { vs->ioc_tag = qio_channel_add_watch( vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_OUT, @@ -296,6 +308,7 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) n_rectangles += n; } } + QLIST_REMOVE(entry, next); g_free(entry); } trace_vnc_job_nrects(&vs, job, n_rectangles); @@ -324,7 +337,7 @@ disconnected: QTAILQ_REMOVE(&queue->jobs, job, next); vnc_unlock_queue(queue); qemu_cond_broadcast(&queue->cond); - g_free(job); + vnc_job_free(job); vs.magic = 0; return 0; } diff --git a/ui/vnc.c b/ui/vnc.c index 952976e964..ccc73bd7aa 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1301,10 +1301,7 @@ static void vnc_disconnect_start(VncState *vs) } trace_vnc_client_disconnect_start(vs, vs->ioc); vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED); - if (vs->ioc_tag) { - g_source_remove(vs->ioc_tag); - vs->ioc_tag = 0; - } + g_clear_handle_id(&vs->ioc_tag, g_source_remove); qio_channel_close(vs->ioc, NULL); vs->disconnecting = TRUE; } @@ -1462,9 +1459,7 @@ static size_t vnc_client_write_plain(VncState *vs) } if (vs->output.offset == 0) { - if (vs->ioc_tag) { - g_source_remove(vs->ioc_tag); - } + g_clear_handle_id(&vs->ioc_tag, g_source_remove); vs->ioc_tag = qio_channel_add_watch( vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR, vnc_client_io, vs, NULL); @@ -1500,9 +1495,7 @@ static void vnc_client_write(VncState *vs) if (vs->output.offset) { vnc_client_write_locked(vs); } else if (vs->ioc != NULL) { - if (vs->ioc_tag) { - g_source_remove(vs->ioc_tag); - } + g_clear_handle_id(&vs->ioc_tag, g_source_remove); vs->ioc_tag = qio_channel_add_watch( vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR, vnc_client_io, vs, NULL); @@ -1638,10 +1631,7 @@ gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED, } if (vs->disconnecting) { - if (vs->ioc_tag != 0) { - g_source_remove(vs->ioc_tag); - } - vs->ioc_tag = 0; + g_clear_handle_id(&vs->ioc_tag, g_source_remove); } return TRUE; } @@ -1684,9 +1674,7 @@ void vnc_write(VncState *vs, const void *data, size_t len) buffer_reserve(&vs->output, len); if (vs->ioc != NULL && buffer_empty(&vs->output)) { - if (vs->ioc_tag) { - g_source_remove(vs->ioc_tag); - } + g_clear_handle_id(&vs->ioc_tag, g_source_remove); vs->ioc_tag = qio_channel_add_watch( vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_OUT, vnc_client_io, vs, NULL); @@ -1734,10 +1722,7 @@ void vnc_flush(VncState *vs) vnc_client_write_locked(vs); } if (vs->disconnecting) { - if (vs->ioc_tag != 0) { - g_source_remove(vs->ioc_tag); - } - vs->ioc_tag = 0; + g_clear_handle_id(&vs->ioc_tag, g_source_remove); } vnc_unlock_output(vs); } @@ -3342,9 +3327,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc, VNC_DEBUG("New client on socket %p\n", vs->sioc); update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); qio_channel_set_blocking(vs->ioc, false, &error_abort); - if (vs->ioc_tag) { - g_source_remove(vs->ioc_tag); - } + g_clear_handle_id(&vs->ioc_tag, g_source_remove); if (websocket) { vs->websocket = 1; if (vd->tlscreds) {