qobject: Replace qobject_incref/QINCREF qobject_decref/QDECREF

Now that we can safely call QOBJECT() on QObject * as well as its
subtypes, we can have macros qobject_ref() / qobject_unref() that work
everywhere instead of having to use QINCREF() / QDECREF() for QObject
and qobject_incref() / qobject_decref() for its subtypes.

The replacement is mechanical, except I broke a long line, and added a
cast in monitor_qmp_cleanup_req_queue_locked(). Unlike
qobject_decref(), qobject_unref() doesn't accept void *.

Note that the new macros evaluate their argument exactly once, thus no
need to shout them.

Backports commit cb3e7f08aeaab0ab13e629ce8496dca150a449ba from qemu
This commit is contained in:
Marc-André Lureau 2018-05-04 10:04:29 -04:00 committed by Lioncash
parent f4b3c5d0bd
commit ab4528c1e4
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
9 changed files with 56 additions and 60 deletions

View file

@ -23,7 +23,7 @@ extern QNull qnull_;
static inline QNull *qnull(void)
{
QINCREF(&qnull_);
qobject_ref(&qnull_);
return &qnull_;
}

View file

@ -15,17 +15,17 @@
* ------------------------------------
*
* - Returning references: A function that returns an object may
* return it as either a weak or a strong reference. If the reference
* is strong, you are responsible for calling QDECREF() on the reference
* when you are done.
* return it as either a weak or a strong reference. If the
* reference is strong, you are responsible for calling
* qobject_unref() on the reference when you are done.
*
* If the reference is weak, the owner of the reference may free it at
* any time in the future. Before storing the reference anywhere, you
* should call QINCREF() to make the reference strong.
* should call qobject_ref() to make the reference strong.
*
* - Transferring ownership: when you transfer ownership of a reference
* by calling a function, you are no longer responsible for calling
* QDECREF() when the reference is no longer needed. In other words,
* qobject_unref() when the reference is no longer needed. In other words,
* when the function returns you must behave as if the reference to the
* passed object was weak.
*/
@ -50,14 +50,6 @@ struct QObject {
_obj ? container_of(&(_obj)->base, QObject, base) : NULL; \
})
/* High-level interface for qobject_incref() */
#define QINCREF(obj) \
qobject_incref(QOBJECT(obj))
/* High-level interface for qobject_decref() */
#define QDECREF(obj) \
qobject_decref(obj ? QOBJECT(obj) : NULL)
/* Required for qobject_to() */
#define QTYPE_CAST_TO_QNull QTYPE_QNULL
#define QTYPE_CAST_TO_QNum QTYPE_QNUM
@ -80,10 +72,7 @@ static inline void qobject_init(QObject *obj, QType type)
obj->base.type = type;
}
/**
* qobject_incref(): Increment QObject's reference count
*/
static inline void qobject_incref(QObject *obj)
static inline void qobject_ref_impl(QObject *obj)
{
if (obj) {
obj->base.refcnt++;
@ -104,11 +93,7 @@ bool qobject_is_equal(const QObject *x, const QObject *y);
*/
void qobject_destroy(QObject *obj);
/**
* qobject_decref(): Decrement QObject's reference count, deallocate
* when it reaches zero
*/
static inline void qobject_decref(QObject *obj)
static inline void qobject_unref_impl(QObject *obj)
{
assert(!obj || obj->base.refcnt);
if (obj && --obj->base.refcnt == 0) {
@ -116,6 +101,17 @@ static inline void qobject_decref(QObject *obj)
}
}
/**
* qobject_ref(): Increment QObject's reference count
*/
#define qobject_ref(obj) qobject_ref_impl(QOBJECT(obj))
/**
* qobject_unref(): Decrement QObject's reference count, deallocate
* when it reaches zero
*/
#define qobject_unref(obj) qobject_unref_impl(QOBJECT(obj))
/**
* qobject_type(): Return the QObject's type
*/

View file

@ -100,7 +100,7 @@ static void qapi_dealloc_type_anything(Visitor *v, const char *name,
QObject **obj, Error **errp)
{
if (obj) {
qobject_decref(*obj);
qobject_unref(*obj);
}
}
@ -108,7 +108,7 @@ static void qapi_dealloc_type_null(Visitor *v, const char *name,
QNull **obj, Error **errp)
{
if (obj) {
QDECREF(*obj);
qobject_unref(*obj);
}
}

View file

@ -463,7 +463,7 @@ static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj,
return;
}
qobject_incref(qobj);
qobject_ref(qobj);
*obj = qobj;
}
@ -511,7 +511,7 @@ static void qobject_input_free(Visitor *v)
qobject_input_stack_object_free(tos);
}
qobject_decref(qiv->root);
qobject_unref(qiv->root);
if (qiv->errname) {
g_string_free(qiv->errname, TRUE);
}
@ -537,7 +537,7 @@ static QObjectInputVisitor *qobject_input_visitor_base_new(QObject *obj)
v->visitor.free = qobject_input_free;
v->root = obj;
qobject_incref(obj);
qobject_ref(obj);
return v;
}

View file

@ -191,7 +191,7 @@ static void qobject_output_type_any(Visitor *v, const char *name, QObject **obj,
Error **errp)
{
QObjectOutputVisitor *qov = to_qov(v);
qobject_incref(*obj);
qobject_ref(*obj);
qobject_output_add_obj(qov, name, *obj);
}
@ -204,7 +204,7 @@ static void qobject_output_type_null(Visitor *v, const char *name,
/* Finish building, and return the root object.
* The root object is never null. The caller becomes the object's
* owner, and should use qobject_decref() when done with it. */
* owner, and should use qobject_unref() when done with it. */
static void qobject_output_complete(Visitor *v, void *opaque)
{
QObjectOutputVisitor *qov = to_qov(v);
@ -228,7 +228,7 @@ static void qobject_output_free(Visitor *v)
g_free(e);
}
qobject_decref(qov->root);
qobject_unref(qov->root);
g_free(qov);
}

View file

@ -123,7 +123,7 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
entry = qdict_find(qdict, key, bucket);
if (entry) {
/* replace key's value */
qobject_decref(entry->value);
qobject_unref(entry->value);
entry->value = value;
} else {
/* allocate a new entry */
@ -373,7 +373,7 @@ QDict *qdict_clone_shallow(const QDict *src)
for (i = 0; i < QDICT_BUCKET_MAX; i++) {
QLIST_FOREACH(entry, &src->table[i], next) {
qobject_incref(entry->value);
qobject_ref(entry->value);
qdict_put_obj(dest, entry->key, entry->value);
}
}
@ -390,7 +390,7 @@ static void qentry_destroy(QDictEntry *e)
assert(e->key != NULL);
assert(e->value != NULL);
qobject_decref(e->value);
qobject_unref(e->value);
g_free(e->key);
g_free(e);
}
@ -493,7 +493,7 @@ static void qdict_flatten_qlist(QList *qlist, QDict *target, const char *prefix)
qdict_flatten_qlist(qobject_to(QList, value), target, new_key);
} else {
/* All other types are moved to the target unchanged. */
qobject_incref(value);
qobject_ref(value);
qdict_put_obj(target, new_key, value);
}
@ -533,7 +533,7 @@ static void qdict_flatten_qdict(QDict *qdict, QDict *target, const char *prefix)
delete = true;
} else if (prefix) {
/* All other objects are moved to the target unchanged. */
qobject_incref(value);
qobject_ref(value);
qdict_put_obj(target, new_key, value);
delete = true;
}
@ -576,7 +576,7 @@ bool qdict_rename_keys(QDict *qdict, const QDictRenames *renames, Error **errp)
}
qobj = qdict_get(qdict, renames->from);
qobject_incref(qobj);
qobject_ref(qobj);
qdict_put_obj(qdict, renames->to, qobj);
qdict_del(qdict, renames->from);
}
@ -611,7 +611,7 @@ void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start)
while (entry != NULL) {
next = qdict_next(src, entry);
if (strstart(entry->key, start, &p)) {
qobject_incref(entry->value);
qobject_ref(entry->value);
qdict_put_obj(*dst, p, entry->value);
qdict_del(src, entry->key);
}
@ -680,7 +680,7 @@ void qdict_array_split(QDict *src, QList **dst)
qdict_extract_subqdict(src, &subqdict, prefix);
assert(qdict_size(subqdict) > 0);
} else {
qobject_incref(subqobj);
qobject_ref(subqobj);
qdict_del(src, indexstr);
}
@ -890,7 +890,7 @@ QObject *qdict_crumple(const QDict *src, Error **errp)
qdict_put_obj(two_level, prefix, QOBJECT(child_dict));
}
qobject_incref(ent->value);
qobject_ref(ent->value);
qdict_put_obj(child_dict, suffix, ent->value);
} else {
if (child) {
@ -898,7 +898,7 @@ QObject *qdict_crumple(const QDict *src, Error **errp)
prefix);
goto error;
}
qobject_incref(ent->value);
qobject_ref(ent->value);
qdict_put_obj(two_level, prefix, ent->value);
}
@ -921,11 +921,11 @@ QObject *qdict_crumple(const QDict *src, Error **errp)
qdict_put_obj(multi_level, ent->key, child);
} else {
qobject_incref(ent->value);
qobject_ref(ent->value);
qdict_put_obj(multi_level, ent->key, ent->value);
}
}
QDECREF(two_level);
qobject_unref(two_level);
two_level = NULL;
/* Step 3: detect if we need to turn our dict into list */
@ -948,10 +948,10 @@ QObject *qdict_crumple(const QDict *src, Error **errp)
goto error;
}
qobject_incref(child);
qobject_ref(child);
qlist_append_obj(qobject_to(QList, dst), child);
}
QDECREF(multi_level);
qobject_unref(multi_level);
multi_level = NULL;
} else {
dst = QOBJECT(multi_level);
@ -961,9 +961,9 @@ QObject *qdict_crumple(const QDict *src, Error **errp)
error:
g_free(prefix);
QDECREF(multi_level);
QDECREF(two_level);
qobject_decref(dst);
qobject_unref(multi_level);
qobject_unref(two_level);
qobject_unref(dst);
return NULL;
}
@ -990,7 +990,7 @@ void qdict_join(QDict *dest, QDict *src, bool overwrite)
next = qdict_next(src, entry);
if (overwrite || !qdict_haskey(dest, entry->key)) {
qobject_incref(entry->value);
qobject_ref(entry->value);
qdict_put_obj(dest, entry->key, entry->value);
qdict_del(src, entry->key);
}

View file

@ -39,7 +39,7 @@ static void qlist_copy_elem(QObject *obj, void *opaque)
{
QList *dst = opaque;
qobject_incref(obj);
qobject_ref(obj);
qlist_append_obj(dst, obj);
}
@ -199,7 +199,7 @@ void qlist_destroy_obj(QObject *obj)
QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) {
QTAILQ_REMOVE(&qlist->head, entry, next);
qobject_decref(entry->value);
qobject_unref(entry->value);
g_free(entry);
}

View file

@ -1001,7 +1001,7 @@ void object_property_set_str(struct uc_struct *uc, Object *obj, const char *valu
QString *qstr = qstring_from_str(value);
object_property_set_qobject(uc, obj, QOBJECT(qstr), name, errp);
QDECREF(qstr);
qobject_unref(qstr);
}
char *object_property_get_str(struct uc_struct *uc, Object *obj, const char *name,
@ -1019,7 +1019,7 @@ char *object_property_get_str(struct uc_struct *uc, Object *obj, const char *nam
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
}
qobject_decref(ret);
qobject_unref(ret);
return retval;
}
@ -1059,7 +1059,7 @@ void object_property_set_bool(struct uc_struct *uc, Object *obj, bool value,
QBool *qbool = qbool_from_bool(value);
object_property_set_qobject(uc, obj, QOBJECT(qbool), name, errp);
QDECREF(qbool);
qobject_unref(qbool);
}
bool object_property_get_bool(struct uc_struct *uc, Object *obj, const char *name,
@ -1080,7 +1080,7 @@ bool object_property_get_bool(struct uc_struct *uc, Object *obj, const char *nam
retval = qbool_get_bool(qbool);
}
qobject_decref(ret);
qobject_unref(ret);
return retval;
}
@ -1090,7 +1090,7 @@ void object_property_set_int(struct uc_struct *uc, Object *obj, int64_t value,
QNum *qnum = qnum_from_int(value);
object_property_set_qobject(uc, obj, QOBJECT(qnum), name, errp);
QDECREF(qnum);
qobject_unref(qnum);
}
int64_t object_property_get_int(struct uc_struct *uc, Object *obj, const char *name,
@ -1110,7 +1110,7 @@ int64_t object_property_get_int(struct uc_struct *uc, Object *obj, const char *n
retval = -1;
}
qobject_decref(ret);
qobject_unref(ret);
return retval;
}
@ -1120,7 +1120,7 @@ void object_property_set_uint(struct uc_struct *uc, Object *obj, uint64_t value,
QNum *qnum = qnum_from_uint(value);
object_property_set_qobject(uc, obj, QOBJECT(qnum), name, errp);
QDECREF(qnum);
qobject_unref(qnum);
}
uint64_t object_property_get_uint(struct uc_struct *uc, Object *obj,
@ -1139,7 +1139,7 @@ uint64_t object_property_get_uint(struct uc_struct *uc, Object *obj,
retval = 0;
}
qobject_decref(ret);
qobject_unref(ret);
return retval;
}

View file

@ -142,7 +142,7 @@ out:
''')
ret += mcgen('''
error_propagate(errp, err);
QDECREF(qmp);
qobject_unref(qmp);
}
''')
return ret