[PULL 3/6] ui/dbus: tear down clipboard callbacks on display finalize

marcandre.lureau@redhat.com posted 6 patches 1 day, 13 hours ago
Maintainers: Gerd Hoffmann <kraxel@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>
[PULL 3/6] ui/dbus: tear down clipboard callbacks on display finalize
Posted by marcandre.lureau@redhat.com 1 day, 13 hours ago
From: GuoHan Zhao <zhaoguohan@kylinos.cn>

The clipboard D-Bus teardown path currently runs when the peer
disappears, but not when DBusDisplay itself is finalized.

That leaves pending clipboard requests and signal handlers associated
with the clipboard proxy active past display teardown.

Add an explicit clipboard fini hook and invoke it from
dbus_display_finalize() so the clipboard teardown also runs during
display destruction.

bixes: ff1a5810f61f ("ui/dbus: add clipboard interface")
Signed-off-by: GuoHan Zhao <zhaoguohan@kylinos.cn>
Message-ID: <20260330091310.42868-1-zhaoguohan@kylinos.cn>
[ Marc-André - Move clipobard finalization to the function]
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 ui/dbus.h           |  1 +
 ui/dbus-clipboard.c | 16 ++++++++++++++++
 ui/dbus.c           |  3 +--
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/ui/dbus.h b/ui/dbus.h
index 1e8c24a48e3..986d7774601 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/dbus-clipboard.c b/ui/dbus-clipboard.c
index 6787a776687..935b6b1a2ac 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 7c54b6a502d..794b65c4ada 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);
-- 
2.53.0