@samitouri / QOSamiQemu / commits / 06e1312b7d

audio/dbus: convert to QOM lifecycle methods

Migrate the D-Bus audio backend from the legacy driver init/fini callbacks to proper QOM realize and finalize methods. The DBusAudio struct fields are now embedded directly in the AudioDbus QOM object instead of being allocated separately as drv_opaque. This allows accessing the backend state through proper QOM type casting with AUDIO_DBUS() rather than casting drv_opaque pointers. Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Marc-André Lureau committed Jan 16, 2026 at 11:39 UTC 06e1312b7d2557b467620ca629f18dac2536b02b
1 file changed +39 -37
audio/dbusaudio.c
+39 -37
@@ -48,21 +48,20 @@
48 #define TYPE_AUDIO_DBUS "audio-dbus"
49 OBJECT_DECLARE_SIMPLE_TYPE(AudioDbus, AUDIO_DBUS)
50
51 +static AudioBackendClass *audio_dbus_parent_class;
52 +
53 struct AudioDbus {
54 AudioMixengBackend parent_obj;
53 -};
54 -
55 -static struct audio_driver dbus_audio_driver;
55
57 -typedef struct DBusAudio {
58 - Audiodev *dev;
56 GDBusObjectManagerServer *server;
57 bool p2p;
58 GDBusObjectSkeleton *audio;
59 QemuDBusDisplay1Audio *iface;
60 GHashTable *out_listeners;
61 GHashTable *in_listeners;
65 -} DBusAudio;
62 +};
63 +
64 +static struct audio_driver dbus_audio_driver;
65
66 typedef struct DBusVoiceOut {
67 HWVoiceOut hw;
@@ -105,7 +104,7 @@ static void *dbus_get_buffer_out(HWVoiceOut *hw, size_t *size)
104
105 static size_t dbus_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
106 {
108 - DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
107 + AudioDbus *da = AUDIO_DBUS(hw->s);
108 DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
109 GHashTableIter iter;
110 QemuDBusDisplay1AudioOutListener *listener = NULL;
@@ -162,9 +161,9 @@ dbus_init_out_listener(QemuDBusDisplay1AudioOutListener *listener,
161 }
162
163 static guint
165 -dbus_audio_get_nsamples(DBusAudio *da)
164 +dbus_audio_get_nsamples(AudioDbus *da)
165 {
167 - AudiodevDBusOptions *opts = &da->dev->u.dbus;
166 + AudiodevDBusOptions *opts = &AUDIO_MIXENG_BACKEND(da)->dev->u.dbus;
167
168 if (opts->has_nsamples && opts->nsamples) {
169 return opts->nsamples;
@@ -176,7 +175,7 @@ dbus_audio_get_nsamples(DBusAudio *da)
175 static int
176 dbus_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
177 {
179 - DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
178 + AudioDbus *da = AUDIO_DBUS(hw->s);
179 DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
180 GHashTableIter iter;
181 QemuDBusDisplay1AudioOutListener *listener = NULL;
@@ -195,7 +194,7 @@ dbus_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
194 static void
195 dbus_fini_out(HWVoiceOut *hw)
196 {
198 - DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
197 + AudioDbus *da = AUDIO_DBUS(hw->s);
198 DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
199 GHashTableIter iter;
200 QemuDBusDisplay1AudioOutListener *listener = NULL;
@@ -214,7 +213,7 @@ dbus_fini_out(HWVoiceOut *hw)
213 static void
214 dbus_enable_out(HWVoiceOut *hw, bool enable)
215 {
217 - DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
216 + AudioDbus *da = AUDIO_DBUS(hw->s);
217 DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
218 GHashTableIter iter;
219 QemuDBusDisplay1AudioOutListener *listener = NULL;
@@ -256,7 +255,7 @@ dbus_volume_out_listener(HWVoiceOut *hw,
255 static void
256 dbus_volume_out(HWVoiceOut *hw, Volume *vol)
257 {
259 - DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
258 + AudioDbus *da = AUDIO_DBUS(hw->s);
259 DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
260 GHashTableIter iter;
261 QemuDBusDisplay1AudioOutListener *listener = NULL;
@@ -290,7 +289,7 @@ dbus_init_in_listener(QemuDBusDisplay1AudioInListener *listener, HWVoiceIn *hw)
289 static int
290 dbus_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
291 {
293 - DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
292 + AudioDbus *da = AUDIO_DBUS(hw->s);
293 DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
294 GHashTableIter iter;
295 QemuDBusDisplay1AudioInListener *listener = NULL;
@@ -309,7 +308,7 @@ dbus_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
308 static void
309 dbus_fini_in(HWVoiceIn *hw)
310 {
312 - DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
311 + AudioDbus *da = AUDIO_DBUS(hw->s);
312 GHashTableIter iter;
313 QemuDBusDisplay1AudioInListener *listener = NULL;
314
@@ -346,7 +345,7 @@ dbus_volume_in_listener(HWVoiceIn *hw,
345 static void
346 dbus_volume_in(HWVoiceIn *hw, Volume *vol)
347 {
349 - DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
348 + AudioDbus *da = AUDIO_DBUS(hw->s);
349 DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
350 GHashTableIter iter;
351 QemuDBusDisplay1AudioInListener *listener = NULL;
@@ -363,7 +362,7 @@ dbus_volume_in(HWVoiceIn *hw, Volume *vol)
362 static size_t
363 dbus_read(HWVoiceIn *hw, void *buf, size_t size)
364 {
366 - DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
365 + AudioDbus *da = AUDIO_DBUS(hw->s);
366 /* DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw); */
367 GHashTableIter iter;
368 QemuDBusDisplay1AudioInListener *listener = NULL;
@@ -398,7 +397,7 @@ dbus_read(HWVoiceIn *hw, void *buf, size_t size)
397 static void
398 dbus_enable_in(HWVoiceIn *hw, bool enable)
399 {
401 - DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
400 + AudioDbus *da = AUDIO_DBUS(hw->s);
401 DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
402 GHashTableIter iter;
403 QemuDBusDisplay1AudioInListener *listener = NULL;
@@ -416,28 +415,31 @@ dbus_enable_in(HWVoiceIn *hw, bool enable)
415 }
416 }
417
419 -static void *
420 -dbus_audio_init(Audiodev *dev, Error **errp)
418 +static bool
419 +audio_dbus_realize(AudioBackend *abe, Audiodev *dev, Error **errp)
420 {
422 - DBusAudio *da;
421 + AudioDbus *da = AUDIO_DBUS(abe);
422
423 if (!qemu_using_dbus_display(errp)) {
425 - return NULL;
424 + qapi_free_Audiodev(dev);
425 + return false;
426 + }
427 +
428 + if (!audio_dbus_parent_class->realize(abe, dev, errp)) {
429 + return false;
430 }
431
428 - da = g_new0(DBusAudio, 1);
429 - da->dev = dev;
432 da->out_listeners = g_hash_table_new_full(g_str_hash, g_str_equal,
431 - g_free, g_object_unref);
433 + g_free, g_object_unref);
434 da->in_listeners = g_hash_table_new_full(g_str_hash, g_str_equal,
433 - g_free, g_object_unref);
434 - return da;
435 + g_free, g_object_unref);
436 + return true;
437 }
438
439 static void
438 -dbus_audio_fini(void *opaque)
440 +audio_dbus_finalize(Object *obj)
441 {
440 - DBusAudio *da = opaque;
442 + AudioDbus *da = AUDIO_DBUS(obj);
443
444 if (da->server) {
445 g_dbus_object_manager_server_unexport(da->server,
@@ -448,14 +450,13 @@ dbus_audio_fini(void *opaque)
450 g_clear_pointer(&da->in_listeners, g_hash_table_unref);
451 g_clear_pointer(&da->out_listeners, g_hash_table_unref);
452 g_clear_object(&da->server);
451 - g_free(da);
453 }
454
455 static void
456 listener_out_vanished_cb(GDBusConnection *connection,
457 gboolean remote_peer_vanished,
458 GError *error,
458 - DBusAudio *da)
459 + AudioDbus *da)
460 {
461 char *name = g_object_get_data(G_OBJECT(connection), "name");
462
@@ -466,7 +467,7 @@ static void
467 listener_in_vanished_cb(GDBusConnection *connection,
468 gboolean remote_peer_vanished,
469 GError *error,
469 - DBusAudio *da)
470 + AudioDbus *da)
471 {
472 char *name = g_object_get_data(G_OBJECT(connection), "name");
473
@@ -482,7 +483,7 @@ dbus_audio_register_listener(AudioMixengBackend *s,
483 GVariant *arg_listener,
484 bool out)
485 {
485 - DBusAudio *da = s->drv_opaque;
486 + AudioDbus *da = AUDIO_DBUS(s);
487 const char *sender =
488 da->p2p ? "p2p" : g_dbus_method_invocation_get_sender(invocation);
489 g_autoptr(GDBusConnection) listener_conn = NULL;
@@ -667,9 +668,8 @@ dbus_audio_set_server(AudioBackend *s,
668 bool p2p,
669 Error **errp)
670 {
670 - DBusAudio *da = AUDIO_MIXENG_BACKEND(s)->drv_opaque;
671 + AudioDbus *da = AUDIO_DBUS(s);
672
672 - g_assert(da);
673 g_assert(!da->server);
674
675 da->server = g_object_ref(server);
@@ -711,8 +711,6 @@ static struct audio_pcm_ops dbus_pcm_ops = {
711
712 static struct audio_driver dbus_audio_driver = {
713 .name = "dbus",
714 - .init = dbus_audio_init,
715 - .fini = dbus_audio_fini,
714 .pcm_ops = &dbus_pcm_ops,
715 .max_voices_out = INT_MAX,
716 .max_voices_in = INT_MAX,
@@ -725,6 +723,9 @@ static void audio_dbus_class_init(ObjectClass *klass, const void *data)
723 AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
724 AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
725
726 + audio_dbus_parent_class = AUDIO_BACKEND_CLASS(object_class_get_parent(klass));
727 +
728 + b->realize = audio_dbus_realize;
729 b->set_dbus_server = dbus_audio_set_server;
730 k->driver = &dbus_audio_driver;
731 }
@@ -734,6 +735,7 @@ static const TypeInfo audio_types[] = {
735 .name = TYPE_AUDIO_DBUS,
736 .parent = TYPE_AUDIO_MIXENG_BACKEND,
737 .instance_size = sizeof(AudioDbus),
738 + .instance_finalize = audio_dbus_finalize,
739 .class_init = audio_dbus_class_init,
740 },
741 };