static QTAILQ_HEAD(ChardevHead, Chardev) chardevs =
QTAILQ_HEAD_INITIALIZER(chardevs);
+static Object *get_chardevs_root(void)
+{
+ return container_get(object_get_root(), "/chardevs");
+}
+
void qemu_chr_be_event(Chardev *s, int event)
{
CharBackend *be = s->be;
{
Chardev *chr = CHARDEV(obj);
+ if (QTAILQ_IN_USE(chr, next)) {
+ QTAILQ_REMOVE(&chardevs, chr, next);
+ }
if (chr->be) {
chr->be->chr = NULL;
}
backend->u.mux.data->chardev = g_strdup(bid);
mux = qemu_chardev_add(id, TYPE_CHARDEV_MUX, backend, errp);
if (mux == NULL) {
- qemu_chr_delete(chr);
+ object_unparent(OBJECT(chr));
chr = NULL;
goto out;
}
}
}
-void qemu_chr_delete(Chardev *chr)
-{
- QTAILQ_REMOVE(&chardevs, chr, next);
- object_unref(OBJECT(chr));
-}
-
ChardevInfoList *qmp_query_chardev(Error **errp)
{
ChardevInfoList *chr_list = NULL;
}
Chardev *qemu_chardev_new(const char *id, const char *typename,
- ChardevBackend *backend, Error **errp)
+ ChardevBackend *backend,
+ Error **errp)
{
+ Object *obj;
Chardev *chr = NULL;
Error *local_err = NULL;
bool be_opened = true;
assert(g_str_has_prefix(typename, "chardev-"));
- chr = CHARDEV(object_new(typename));
+ obj = object_new(typename);
+ chr = CHARDEV(obj);
chr->label = g_strdup(id);
qemu_char_open(chr, backend, &be_opened, &local_err);
if (local_err) {
- error_propagate(errp, local_err);
- object_unref(OBJECT(chr));
- return NULL;
+ goto end;
}
if (!chr->filename) {
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}
+ if (id) {
+ object_property_add_child(get_chardevs_root(), id, obj, &local_err);
+ if (local_err) {
+ goto end;
+ }
+ object_unref(obj);
+ }
+
+end:
+ if (local_err) {
+ error_propagate(errp, local_err);
+ object_unref(obj);
+ return NULL;
+ }
+
return chr;
}
"Chardev '%s' cannot be unplugged in record/replay mode", id);
return;
}
- qemu_chr_delete(chr);
+ object_unparent(OBJECT(chr));
}
void qemu_chr_cleanup(void)
{
- Chardev *chr, *tmp;
-
- QTAILQ_FOREACH_SAFE(chr, &chardevs, next, tmp) {
- qemu_chr_delete(chr);
- }
+ object_unparent(get_chardevs_root());
}
static void register_types(void)
#ifndef CONFIG_USER_ONLY
qemu_chr_fe_deinit(&s->chr);
- qemu_chr_delete(chr);
+ object_unparent(OBJECT(chr));
#endif
}
monitor_init(mon_chr, 0);
} else {
if (qemu_chr_fe_get_driver(&s->chr)) {
- qemu_chr_delete(qemu_chr_fe_get_driver(&s->chr));
+ object_unparent(OBJECT(qemu_chr_fe_get_driver(&s->chr)));
}
mon_chr = s->mon_chr;
memset(s, 0, sizeof(GDBState));
g_assert_cmpint(ret, ==, 4);
qemu_chr_fe_deinit(&be);
- qemu_chr_delete(chr);
+ object_unparent(OBJECT(chr));
}
static void char_stdio_test(void)
g_free(data);
qemu_chr_fe_deinit(&be);
- qemu_chr_delete(chr);
+ object_unparent(OBJECT(chr));
}
static void char_mux_test(void)
qemu_chr_fe_deinit(&chr_be1);
qemu_chr_fe_deinit(&chr_be2);
- qemu_chr_delete(chr);
+ object_unparent(OBJECT(chr));
}
static void char_null_test(void)
g_assert_cmpint(ret, ==, 4);
qemu_chr_fe_deinit(&be);
- qemu_chr_delete(chr);
+ object_unparent(OBJECT(chr));
}
static void char_invalid_test(void)