diff --git a/qom/object.c b/qom/object.c index 0ac3bc1..284fa38 100644 --- a/qom/object.c +++ b/qom/object.c @@ -377,14 +377,22 @@ static void object_property_del_all(Object *obj) ObjectProperty *prop; GHashTableIter iter; gpointer key, value; + bool released; - g_hash_table_iter_init(&iter, obj->properties); - while (g_hash_table_iter_next(&iter, &key, &value)) { - prop = value; - if (prop->release) { - prop->release(obj, prop->name, prop->opaque); + do { + released = false; + g_hash_table_iter_init(&iter, obj->properties); + while (g_hash_table_iter_next(&iter, &key, &value)) { + prop = value; + if (prop->release) { + prop->release(obj, prop->name, prop->opaque); + prop->release = NULL; + released = true; + break; + } + g_hash_table_iter_remove(&iter); } - } + } while (released); g_hash_table_unref(obj->properties); } @@ -401,7 +409,15 @@ static void object_property_del_child(Object *obj, Object *child, Error **errp) if (object_property_is_child(prop) && prop->opaque == child) { if (prop->release) { prop->release(obj, prop->name, prop->opaque); + prop->release = NULL; } + break; + } + } + g_hash_table_iter_init(&iter, obj->properties); + while (g_hash_table_iter_next(&iter, &key, &value)) { + prop = value; + if (object_property_is_child(prop) && prop->opaque == child) { g_hash_table_iter_remove(&iter); break; } @@ -856,7 +872,7 @@ void object_ref(Object *obj) if (!obj) { return; } - atomic_inc(&obj->ref); + atomic_inc(&obj->ref); } void object_unref(Object *obj) @@ -864,7 +880,7 @@ void object_unref(Object *obj) if (!obj) { return; } - g_assert(obj->ref > 0); + g_assert_cmpint(obj->ref, >, 0); /* parent always holds a reference to its children */ if (atomic_fetch_dec(&obj->ref) == 1) {