diff --git a/include/qapi/qmp/qbool.h b/include/qapi/qmp/qbool.h index d9256e4268778d06505f076c6a48ad8213d2fb44..836d078866bdf00be53694b10be2dc6a81a67199 100644 --- a/include/qapi/qmp/qbool.h +++ b/include/qapi/qmp/qbool.h @@ -25,5 +25,6 @@ typedef struct QBool { QBool *qbool_from_bool(bool value); bool qbool_get_bool(const QBool *qb); QBool *qobject_to_qbool(const QObject *obj); +void qbool_destroy_obj(QObject *obj); #endif /* QBOOL_H */ diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h index 787c658967ce3a42256d4741adaf4f55b48a9e0c..6c2a0e501ef279bab1d9b5024627e931d3575cb3 100644 --- a/include/qapi/qmp/qdict.h +++ b/include/qapi/qmp/qdict.h @@ -48,6 +48,7 @@ void qdict_iter(const QDict *qdict, void *opaque); const QDictEntry *qdict_first(const QDict *qdict); const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry); +void qdict_destroy_obj(QObject *obj); /* Helper to qdict_put_obj(), accepts any object */ #define qdict_put(qdict, key, obj) \ diff --git a/include/qapi/qmp/qfloat.h b/include/qapi/qmp/qfloat.h index 46745e50d146ae86011a88b55571605c389085ad..a8af2a89b257570bafdfb7dd7373eefcec988ad5 100644 --- a/include/qapi/qmp/qfloat.h +++ b/include/qapi/qmp/qfloat.h @@ -25,5 +25,6 @@ typedef struct QFloat { QFloat *qfloat_from_double(double value); double qfloat_get_double(const QFloat *qi); QFloat *qobject_to_qfloat(const QObject *obj); +void qfloat_destroy_obj(QObject *obj); #endif /* QFLOAT_H */ diff --git a/include/qapi/qmp/qint.h b/include/qapi/qmp/qint.h index 339a9abb8fbe860b28b6fda83806bf20c899d720..049e5280792289a64e580f2a1a41976386e22f73 100644 --- a/include/qapi/qmp/qint.h +++ b/include/qapi/qmp/qint.h @@ -24,5 +24,6 @@ typedef struct QInt { QInt *qint_from_int(int64_t value); int64_t qint_get_int(const QInt *qi); QInt *qobject_to_qint(const QObject *obj); +void qint_destroy_obj(QObject *obj); #endif /* QINT_H */ diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h index b1bf7852c5e4917465f34d85eecafa02fae5d2d3..a84117ecb151f8e8cc110b38a01f0a2b62e0adde 100644 --- a/include/qapi/qmp/qlist.h +++ b/include/qapi/qmp/qlist.h @@ -49,6 +49,7 @@ QObject *qlist_peek(QList *qlist); int qlist_empty(const QList *qlist); size_t qlist_size(const QList *qlist); QList *qobject_to_qlist(const QObject *obj); +void qlist_destroy_obj(QObject *obj); static inline const QListEntry *qlist_first(const QList *qlist) { diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h index 4b96ed5837212e18c62fbed10cab89668f99a14a..550ba40ddecc26fd894895e6e984e660eff15cd1 100644 --- a/include/qapi/qmp/qobject.h +++ b/include/qapi/qmp/qobject.h @@ -47,15 +47,8 @@ typedef enum { QTYPE_MAX, } qtype_code; -struct QObject; - -typedef struct QType { - qtype_code code; - void (*destroy)(struct QObject *); -} QType; - typedef struct QObject { - const QType *type; + qtype_code type; size_t refcnt; } QObject; @@ -71,9 +64,12 @@ typedef struct QObject { qobject_decref(obj ? QOBJECT(obj) : NULL) /* Initialize an object to default values */ -#define QOBJECT_INIT(obj, qtype_type) \ - obj->base.refcnt = 1; \ - obj->base.type = qtype_type +static inline void qobject_init(QObject *obj, qtype_code type) +{ + assert(QTYPE_NONE < type && type < QTYPE_MAX); + obj->refcnt = 1; + obj->type = type; +} /** * qobject_incref(): Increment QObject's reference count @@ -84,6 +80,11 @@ static inline void qobject_incref(QObject *obj) obj->refcnt++; } +/** + * qobject_destroy(): Free resources used by the object + */ +void qobject_destroy(QObject *obj); + /** * qobject_decref(): Decrement QObject's reference count, deallocate * when it reaches zero @@ -92,9 +93,7 @@ static inline void qobject_decref(QObject *obj) { assert(!obj || obj->refcnt); if (obj && --obj->refcnt == 0) { - assert(obj->type != NULL); - assert(obj->type->destroy != NULL); - obj->type->destroy(obj); + qobject_destroy(obj); } } @@ -103,8 +102,8 @@ static inline void qobject_decref(QObject *obj) */ static inline qtype_code qobject_type(const QObject *obj) { - assert(obj->type != NULL); - return obj->type->code; + assert(QTYPE_NONE < obj->type && obj->type < QTYPE_MAX); + return obj->type; } extern QObject qnull_; diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h index 34675a7fc03827780b18ba3265b2e63f6cd6ed98..df7df558b22b54e637cfecfa0c06fde8f4d3f756 100644 --- a/include/qapi/qmp/qstring.h +++ b/include/qapi/qmp/qstring.h @@ -32,5 +32,6 @@ void qstring_append_int(QString *qstring, int64_t value); void qstring_append(QString *qstring, const char *str); void qstring_append_chr(QString *qstring, int c); QString *qobject_to_qstring(const QObject *obj); +void qstring_destroy_obj(QObject *obj); #endif /* QSTRING_H */ diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs index 0031e8b6919358f97ffd9514e832003c1cf702b1..bed55084bbd7a37c08839643bad9575c4878c0b2 100644 --- a/qobject/Makefile.objs +++ b/qobject/Makefile.objs @@ -1,2 +1,2 @@ util-obj-y = qnull.o qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o -util-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o +util-obj-y += qjson.o qobject.o json-lexer.o json-streamer.o json-parser.o diff --git a/qobject/qbool.c b/qobject/qbool.c index bc6535fa49a5ab2af39732d44c8a22fe751a7036..856c7433577041982950b6ca14cbbefed9b42696 100644 --- a/qobject/qbool.c +++ b/qobject/qbool.c @@ -15,13 +15,6 @@ #include "qapi/qmp/qobject.h" #include "qemu-common.h" -static void qbool_destroy_obj(QObject *obj); - -static const QType qbool_type = { - .code = QTYPE_QBOOL, - .destroy = qbool_destroy_obj, -}; - /** * qbool_from_bool(): Create a new QBool from a bool * @@ -32,8 +25,8 @@ QBool *qbool_from_bool(bool value) QBool *qb; qb = g_malloc(sizeof(*qb)); + qobject_init(QOBJECT(qb), QTYPE_QBOOL); qb->value = value; - QOBJECT_INIT(qb, &qbool_type); return qb; } @@ -61,7 +54,7 @@ QBool *qobject_to_qbool(const QObject *obj) * qbool_destroy_obj(): Free all memory allocated by a * QBool object */ -static void qbool_destroy_obj(QObject *obj) +void qbool_destroy_obj(QObject *obj) { assert(obj != NULL); g_free(qobject_to_qbool(obj)); diff --git a/qobject/qdict.c b/qobject/qdict.c index 2d67bf157951ad50d303736ab85532c772691a12..eeade159ccfb89796486180d002640558d7b6211 100644 --- a/qobject/qdict.c +++ b/qobject/qdict.c @@ -19,13 +19,6 @@ #include "qemu/queue.h" #include "qemu-common.h" -static void qdict_destroy_obj(QObject *obj); - -static const QType qdict_type = { - .code = QTYPE_QDICT, - .destroy = qdict_destroy_obj, -}; - /** * qdict_new(): Create a new QDict * @@ -36,7 +29,7 @@ QDict *qdict_new(void) QDict *qdict; qdict = g_malloc0(sizeof(*qdict)); - QOBJECT_INIT(qdict, &qdict_type); + qobject_init(QOBJECT(qdict), QTYPE_QDICT); return qdict; } @@ -441,7 +434,7 @@ void qdict_del(QDict *qdict, const char *key) /** * qdict_destroy_obj(): Free all the memory allocated by a QDict */ -static void qdict_destroy_obj(QObject *obj) +void qdict_destroy_obj(QObject *obj) { int i; QDict *qdict; diff --git a/qobject/qfloat.c b/qobject/qfloat.c index c86516327f97b1d9a5bd50077d0138da23d9d212..87d89a772122eeed4cafb5f6f7899f44a8fffdfd 100644 --- a/qobject/qfloat.c +++ b/qobject/qfloat.c @@ -15,13 +15,6 @@ #include "qapi/qmp/qobject.h" #include "qemu-common.h" -static void qfloat_destroy_obj(QObject *obj); - -static const QType qfloat_type = { - .code = QTYPE_QFLOAT, - .destroy = qfloat_destroy_obj, -}; - /** * qfloat_from_int(): Create a new QFloat from a float * @@ -32,8 +25,8 @@ QFloat *qfloat_from_double(double value) QFloat *qf; qf = g_malloc(sizeof(*qf)); + qobject_init(QOBJECT(qf), QTYPE_QFLOAT); qf->value = value; - QOBJECT_INIT(qf, &qfloat_type); return qf; } @@ -61,7 +54,7 @@ QFloat *qobject_to_qfloat(const QObject *obj) * qfloat_destroy_obj(): Free all memory allocated by a * QFloat object */ -static void qfloat_destroy_obj(QObject *obj) +void qfloat_destroy_obj(QObject *obj) { assert(obj != NULL); g_free(qobject_to_qfloat(obj)); diff --git a/qobject/qint.c b/qobject/qint.c index 999688e9ce56ff042538120d326e16e8a5359f35..7cba9adf40c0b85570ec89f5c07e78e2d65db5f3 100644 --- a/qobject/qint.c +++ b/qobject/qint.c @@ -14,13 +14,6 @@ #include "qapi/qmp/qobject.h" #include "qemu-common.h" -static void qint_destroy_obj(QObject *obj); - -static const QType qint_type = { - .code = QTYPE_QINT, - .destroy = qint_destroy_obj, -}; - /** * qint_from_int(): Create a new QInt from an int64_t * @@ -31,8 +24,8 @@ QInt *qint_from_int(int64_t value) QInt *qi; qi = g_malloc(sizeof(*qi)); + qobject_init(QOBJECT(qi), QTYPE_QINT); qi->value = value; - QOBJECT_INIT(qi, &qint_type); return qi; } @@ -60,7 +53,7 @@ QInt *qobject_to_qint(const QObject *obj) * qint_destroy_obj(): Free all memory allocated by a * QInt object */ -static void qint_destroy_obj(QObject *obj) +void qint_destroy_obj(QObject *obj) { assert(obj != NULL); g_free(qobject_to_qint(obj)); diff --git a/qobject/qlist.c b/qobject/qlist.c index 298003aaf761280e3e523f22cd59606d34f786ff..3c045aed11e95b3b4af9662b34c5e38c1b572cd7 100644 --- a/qobject/qlist.c +++ b/qobject/qlist.c @@ -15,13 +15,6 @@ #include "qemu/queue.h" #include "qemu-common.h" -static void qlist_destroy_obj(QObject *obj); - -static const QType qlist_type = { - .code = QTYPE_QLIST, - .destroy = qlist_destroy_obj, -}; - /** * qlist_new(): Create a new QList * @@ -32,8 +25,8 @@ QList *qlist_new(void) QList *qlist; qlist = g_malloc(sizeof(*qlist)); + qobject_init(QOBJECT(qlist), QTYPE_QLIST); QTAILQ_INIT(&qlist->head); - QOBJECT_INIT(qlist, &qlist_type); return qlist; } @@ -151,7 +144,7 @@ QList *qobject_to_qlist(const QObject *obj) /** * qlist_destroy_obj(): Free all the memory allocated by a QList */ -static void qlist_destroy_obj(QObject *obj) +void qlist_destroy_obj(QObject *obj) { QList *qlist; QListEntry *entry, *next_entry; diff --git a/qobject/qnull.c b/qobject/qnull.c index 9873e266e616ed5082113039c7bdb30616c131da..5f7ba4d01a9dafef9ce5f93a0c9561ffffaa4ab7 100644 --- a/qobject/qnull.c +++ b/qobject/qnull.c @@ -13,17 +13,7 @@ #include "qemu-common.h" #include "qapi/qmp/qobject.h" -static void qnull_destroy_obj(QObject *obj) -{ - assert(0); -} - -static const QType qnull_type = { - .code = QTYPE_QNULL, - .destroy = qnull_destroy_obj, -}; - QObject qnull_ = { - .type = &qnull_type, + .type = QTYPE_QNULL, .refcnt = 1, }; diff --git a/qobject/qobject.c b/qobject/qobject.c new file mode 100644 index 0000000000000000000000000000000000000000..1df315ab013dac5fb4513a519881a0e4899ed932 --- /dev/null +++ b/qobject/qobject.c @@ -0,0 +1,34 @@ +/* + * QObject + * + * Copyright (C) 2015 Red Hat, Inc. + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 + * or later. See the COPYING.LIB file in the top-level directory. + */ + +#include "qemu-common.h" +#include "qapi/qmp/qbool.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qfloat.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qlist.h" +#include "qapi/qmp/qstring.h" + +static void (*qdestroy[QTYPE_MAX])(QObject *) = { + [QTYPE_NONE] = NULL, /* No such object exists */ + [QTYPE_QNULL] = NULL, /* qnull_ is indestructible */ + [QTYPE_QINT] = qint_destroy_obj, + [QTYPE_QSTRING] = qstring_destroy_obj, + [QTYPE_QDICT] = qdict_destroy_obj, + [QTYPE_QLIST] = qlist_destroy_obj, + [QTYPE_QFLOAT] = qfloat_destroy_obj, + [QTYPE_QBOOL] = qbool_destroy_obj, +}; + +void qobject_destroy(QObject *obj) +{ + assert(!obj->refcnt); + assert(QTYPE_QNULL < obj->type && obj->type < QTYPE_MAX); + qdestroy[obj->type](obj); +} diff --git a/qobject/qstring.c b/qobject/qstring.c index cb72dfbfc8ca0bb0fcdf99f6b4572f8fdf135568..f44c5c424d1ed9cbb0b343b0647a74ea991f24f0 100644 --- a/qobject/qstring.c +++ b/qobject/qstring.c @@ -14,13 +14,6 @@ #include "qapi/qmp/qstring.h" #include "qemu-common.h" -static void qstring_destroy_obj(QObject *obj); - -static const QType qstring_type = { - .code = QTYPE_QSTRING, - .destroy = qstring_destroy_obj, -}; - /** * qstring_new(): Create a new empty QString * @@ -49,6 +42,7 @@ QString *qstring_from_substr(const char *str, int start, int end) QString *qstring; qstring = g_malloc(sizeof(*qstring)); + qobject_init(QOBJECT(qstring), QTYPE_QSTRING); qstring->length = end - start + 1; qstring->capacity = qstring->length; @@ -57,7 +51,6 @@ QString *qstring_from_substr(const char *str, int start, int end) memcpy(qstring->string, str + start, qstring->length); qstring->string[qstring->length] = 0; - QOBJECT_INIT(qstring, &qstring_type); return qstring; } @@ -138,7 +131,7 @@ const char *qstring_get_str(const QString *qstring) * qstring_destroy_obj(): Free all memory allocated by a QString * object */ -static void qstring_destroy_obj(QObject *obj) +void qstring_destroy_obj(QObject *obj) { QString *qs;