qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 05/21] char: add a /chardevs container


From: Marc-André Lureau
Subject: [Qemu-devel] [PATCH v2 05/21] char: add a /chardevs container
Date: Mon, 27 Feb 2017 17:41:46 +0400

Add a /chardevs container object to hold the list of chardevs.
(Note: QTAILQ chardevs is going away in the following commits)

Signed-off-by: Marc-André Lureau <address@hidden>
---
 include/sysemu/char.h       |  8 -------
 chardev/char.c              | 57 +++++++++++++++++++++++++++++++--------------
 gdbstub.c                   |  4 ++--
 hw/usb/ccid-card-passthru.c |  2 +-
 hw/usb/redirect.c           |  2 +-
 net/vhost-user.c            |  2 +-
 tests/test-char.c           |  8 +++----
 tests/vhost-user-test.c     |  2 +-
 8 files changed, 49 insertions(+), 36 deletions(-)

diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index a30ff3fa80..98903f31e4 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -171,14 +171,6 @@ int qemu_chr_fe_wait_connected(CharBackend *be, Error 
**errp);
 Chardev *qemu_chr_new_noreplay(const char *label, const char *filename);
 
 /**
- * @qemu_chr_delete:
- *
- * Destroy a character backend and remove it from the list of
- * identified character backends.
- */
-void qemu_chr_delete(Chardev *chr);
-
-/**
  * @qemu_chr_fe_set_echo:
  *
  * Ask the backend to override its normal echo setting.  This only really
diff --git a/chardev/char.c b/chardev/char.c
index 4f253b3eca..4e55f77dce 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -45,6 +45,11 @@
 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;
@@ -413,6 +418,9 @@ static void char_finalize(Object *obj)
 {
     Chardev *chr = CHARDEV(obj);
 
+    if (QTAILQ_IN_USE(chr, next)) {
+        QTAILQ_REMOVE(&chardevs, chr, next);
+    }
     if (chr->be) {
         chr->be->chr = NULL;
     }
@@ -946,7 +954,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts,
         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;
         }
@@ -1060,12 +1068,6 @@ void qemu_chr_fe_disconnect(CharBackend *be)
     }
 }
 
-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;
@@ -1225,22 +1227,33 @@ void qemu_chr_set_feature(Chardev *chr,
 }
 
 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));
+    if (id) {
+        obj = object_new_with_props(typename, get_chardevs_root(),
+                                    id, &local_err, NULL);
+    } else {
+        obj = object_new(typename);
+    }
+    if (local_err) {
+        assert(!obj);
+        goto end;
+    }
+
+    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) {
@@ -1250,6 +1263,18 @@ Chardev *qemu_chardev_new(const char *id, const char 
*typename,
         qemu_chr_be_event(chr, CHR_EVENT_OPENED);
     }
 
+end:
+    if (local_err) {
+        error_propagate(errp, local_err);
+        if (chr) {
+            if (id) {
+                object_unparent(OBJECT(chr));
+            } else {
+                object_unref(OBJECT(chr));
+            }
+        }
+        return NULL;
+    }
     return chr;
 }
 
@@ -1298,16 +1323,12 @@ void qmp_chardev_remove(const char *id, Error **errp)
             "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)
diff --git a/gdbstub.c b/gdbstub.c
index 991115361e..07ebfe9626 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1611,7 +1611,7 @@ void gdb_exit(CPUArchState *env, int code)
 
 #ifndef CONFIG_USER_ONLY
   qemu_chr_fe_deinit(&s->chr);
-  qemu_chr_delete(chr);
+  object_unparent(OBJECT(chr));
 #endif
 }
 
@@ -1912,7 +1912,7 @@ int gdbserver_start(const char *device)
         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));
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index daab0d56cf..a41b0d6ec5 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -267,7 +267,7 @@ static void ccid_card_vscard_drop_connection(PassthruState 
*card)
     Chardev *chr = qemu_chr_fe_get_driver(&card->cs);
 
     qemu_chr_fe_deinit(&card->cs);
-    qemu_chr_delete(chr);
+    object_unparent(OBJECT(chr));
     card->vscard_in_pos = card->vscard_in_hdr = 0;
 }
 
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 0efe62f725..b001a27f05 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1433,7 +1433,7 @@ static void usbredir_unrealize(USBDevice *udev, Error 
**errp)
     Chardev *chr = qemu_chr_fe_get_driver(&dev->cs);
 
     qemu_chr_fe_deinit(&dev->cs);
-    qemu_chr_delete(chr);
+    object_unparent(OBJECT(chr));
 
     /* Note must be done after qemu_chr_close, as that causes a close event */
     qemu_bh_delete(dev->chardev_close_bh);
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 77b8110f8c..4db26ca4b1 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -154,7 +154,7 @@ static void vhost_user_cleanup(NetClientState *nc)
         Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
 
         qemu_chr_fe_deinit(&s->chr);
-        qemu_chr_delete(chr);
+        object_unparent(OBJECT(chr));
     }
 
     qemu_purge_queued_packets(nc);
diff --git a/tests/test-char.c b/tests/test-char.c
index da69f110e4..71de4b35ee 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -53,7 +53,7 @@ static void char_stdio_test_subprocess(void)
     g_assert_cmpint(ret, ==, 4);
 
     qemu_chr_fe_deinit(&be);
-    qemu_chr_delete(chr);
+    object_unparent(OBJECT(chr));
 }
 
 static void char_stdio_test(void)
@@ -103,7 +103,7 @@ static void char_ringbuf_test(void)
     g_free(data);
 
     qemu_chr_fe_deinit(&be);
-    qemu_chr_delete(chr);
+    object_unparent(OBJECT(chr));
 }
 
 static void char_mux_test(void)
@@ -179,7 +179,7 @@ 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)
@@ -222,7 +222,7 @@ 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)
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 2c45c7b29f..3c0e75b797 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -490,7 +490,7 @@ static gboolean _test_server_free(TestServer *server)
     Chardev *chr = qemu_chr_fe_get_driver(&server->chr);
 
     qemu_chr_fe_deinit(&server->chr);
-    qemu_chr_delete(chr);
+    object_unparent(OBJECT(chr));
 
     for (i = 0; i < server->fds_num; i++) {
         close(server->fds[i]);
-- 
2.12.0.rc2.3.gc93709801




reply via email to

[Prev in Thread] Current Thread [Next in Thread]