if (ti->instance_size == 0) {
ti->abstract = true;
}
-
+ if (type_is_ancestor(ti, type_interface)) {
+ assert(ti->instance_size == 0);
+ assert(ti->abstract);
+ assert(!ti->instance_init);
+ assert(!ti->instance_post_init);
+ assert(!ti->instance_finalize);
+ assert(!ti->num_interfaces);
+ }
ti->class = g_malloc0(ti->class_size);
parent = type_get_parent(ti);
GSList *e;
int i;
- g_assert_cmpint(parent->class_size, <=, ti->class_size);
+ g_assert(parent->class_size <= ti->class_size);
memcpy(ti->class, parent->class, parent->class_size);
ti->class->interfaces = NULL;
ti->class->properties = g_hash_table_new_full(
g_assert(type != NULL);
type_initialize(type);
- g_assert_cmpint(type->instance_size, >=, sizeof(Object));
+ g_assert(type->instance_size >= sizeof(Object));
g_assert(type->abstract == false);
- g_assert_cmpint(size, >=, type->instance_size);
+ g_assert(size >= type->instance_size);
memset(obj, 0, type->instance_size);
obj->class = type->class;
object_initialize_with_type(data, size, type);
}
+void object_initialize_child(Object *parentobj, const char *propname,
+ void *childobj, size_t size, const char *type,
+ Error **errp, ...)
+{
+ va_list vargs;
+
+ va_start(vargs, errp);
+ object_initialize_childv(parentobj, propname, childobj, size, type, errp,
+ vargs);
+ va_end(vargs);
+}
+
+void object_initialize_childv(Object *parentobj, const char *propname,
+ void *childobj, size_t size, const char *type,
+ Error **errp, va_list vargs)
+{
+ Error *local_err = NULL;
+ Object *obj;
+
+ object_initialize(childobj, size, type);
+ obj = OBJECT(childobj);
+
+ object_set_propv(obj, &local_err, vargs);
+ if (local_err) {
+ goto out;
+ }
+
+ object_property_add_child(parentobj, propname, obj, &local_err);
+ if (local_err) {
+ goto out;
+ }
+
+ if (object_dynamic_cast(obj, TYPE_USER_CREATABLE)) {
+ user_creatable_complete(obj, &local_err);
+ if (local_err) {
+ object_unparent(obj);
+ goto out;
+ }
+ }
+
+ /*
+ * Since object_property_add_child added a reference to the child object,
+ * we can drop the reference added by object_initialize(), so the child
+ * property will own the only reference to the object.
+ */
+ object_unref(obj);
+
+out:
+ if (local_err) {
+ error_propagate(errp, local_err);
+ object_unref(obj);
+ }
+}
+
static inline bool object_property_is_child(ObjectProperty *prop)
{
return strstart(prop->type, "child<", NULL);
object_property_del_all(obj);
object_deinit(obj, ti);
- g_assert_cmpint(obj->ref, ==, 0);
+ g_assert(obj->ref == 0);
if (obj->free) {
obj->free(obj);
}
if (!obj) {
return;
}
- g_assert_cmpint(obj->ref, >, 0);
+ g_assert(obj->ref > 0);
/* parent always holds a reference to its children */
if (atomic_fetch_dec(&obj->ref) == 1) {
ObjectClass *klass)
{
g_hash_table_iter_init(&iter->iter, klass->properties);
- iter->nextclass = klass;
+ iter->nextclass = object_class_get_parent(klass);
}
ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name,
return;
}
- object_ref(new_target);
*child = new_target;
- object_unref(old_target);
+ if (prop->flags == OBJ_PROP_LINK_STRONG) {
+ object_ref(new_target);
+ object_unref(old_target);
+ }
}
static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part)
{
LinkProperty *prop = opaque;
- if ((prop->flags & OBJ_PROP_LINK_UNREF_ON_RELEASE) && *prop->child) {
+ if ((prop->flags & OBJ_PROP_LINK_STRONG) && *prop->child) {
object_unref(*prop->child);
}
g_free(prop);
op->description = g_strdup(description);
}
-static void object_instance_init(Object *obj)
+static void object_class_init(ObjectClass *klass, void *data)
{
- object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
+ object_class_property_add_str(klass, "type", qdev_get_type,
+ NULL, &error_abort);
}
static void register_types(void)
static TypeInfo object_info = {
.name = TYPE_OBJECT,
.instance_size = sizeof(Object),
- .instance_init = object_instance_init,
+ .class_init = object_class_init,
.abstract = true,
};