@samitouri / QOSamiQemu / commits / 285689a3f1

ui: add display cleanup infrastructure

Add a cleanup callback to QemuDisplay and a qemu_display_cleanup() function that iterates all registered display types and calls their cleanup handler. Wire it into qemu_cleanup() in runstate.c, replacing the ad-hoc vnc_cleanup() call. This provides a structured alternative to atexit() handlers, giving deterministic teardown ordering and making resource leaks visible to sanitizers. The cleanup should happen before user_creatable_cleanup(), since some display have weak user-creatable references to cleanup before. Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-ID: <20260623-b4-ui-v4-15-4656aec3398d@redhat.com>

Marc-André Lureau committed Jun 23, 2026 at 11:44 UTC 285689a3f1f3a60f9cca56156e587a2008231bd3
3 files changed +22 -8
include/ui/console.h
+2
@@ -403,6 +403,7 @@ struct QemuDisplay {
403 DisplayType type;
404 void (*early_init)(DisplayOptions *opts);
405 void (*init)(DisplayState *ds, DisplayOptions *opts);
406 + void (*cleanup)(void);
407 const char *vc;
408 };
409
@@ -411,6 +412,7 @@ bool qemu_display_find_default(DisplayOptions *opts);
412 void qemu_display_early_init(DisplayOptions *opts);
413 void qemu_display_init(DisplayState *ds, DisplayOptions *opts);
414 const char *qemu_display_get_vc(DisplayOptions *opts);
415 +void qemu_display_cleanup(void);
416 void qemu_display_help(void);
417
418 /* vnc.c */
system/runstate.c
+1 -7
@@ -62,7 +62,6 @@
62 #include "system/system.h"
63 #include "system/tpm.h"
64 #include "ui/console.h"
65 -#include "ui/qemu-spice-module.h"
65
66 #include "trace.h"
67
@@ -1046,12 +1045,7 @@ void qemu_cleanup(int status)
1045 audio_cleanup();
1046 monitor_cleanup();
1047 qemu_chr_cleanup();
1048 + qemu_display_cleanup();
1049 user_creatable_cleanup();
1050 -#ifdef CONFIG_VNC
1051 - vnc_cleanup();
1052 -#endif
1053 -#ifdef CONFIG_SPICE
1054 - qemu_spice.cleanup();
1055 -#endif
1050 /* TODO: unref root container, check all devices are ok */
1051 }
ui/console.c
+19 -1
@@ -42,6 +42,7 @@
42 #include "qemu/memfd.h"
43 #include "ui/vt100.h"
44 #include "vgafont.h"
45 +#include "ui/qemu-spice.h"
46
47 #include "console-priv.h"
48
@@ -575,7 +576,7 @@ void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *gl)
576 {
577 /* display has opengl support */
578 assert(con);
578 - if (con->gl) {
579 + if (gl && con->gl) {
580 error_report("The console already has an OpenGL context.");
581 exit(1);
582 }
@@ -1414,6 +1415,23 @@ void qemu_display_init(DisplayState *ds, DisplayOptions *opts)
1415 dpys[opts->type]->init(ds, opts);
1416 }
1417
1418 +void qemu_display_cleanup(void)
1419 +{
1420 + int i;
1421 +
1422 + for (i = 0; i < DISPLAY_TYPE__MAX; i++) {
1423 + if (dpys[i] && dpys[i]->cleanup) {
1424 + dpys[i]->cleanup();
1425 + }
1426 + }
1427 +#ifdef CONFIG_VNC
1428 + vnc_cleanup();
1429 +#endif
1430 +#ifdef CONFIG_SPICE
1431 + qemu_spice.cleanup();
1432 +#endif
1433 +}
1434 +
1435 const char *qemu_display_get_vc(DisplayOptions *opts)
1436 {
1437 #ifdef CONFIG_PIXMAN