From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:39174) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UYERk-0001Ib-0i for qemu-devel@nongnu.org; Fri, 03 May 2013 07:46:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UYERi-0007OS-55 for qemu-devel@nongnu.org; Fri, 03 May 2013 07:46:39 -0400 Message-ID: <5183A39A.3000806@suse.de> Date: Fri, 03 May 2013 13:46:34 +0200 From: =?UTF-8?B?QW5kcmVhcyBGw6RyYmVy?= MIME-Version: 1.0 References: <1367525344-7755-1-git-send-email-hpoussin@reactos.org> <1367525344-7755-3-git-send-email-hpoussin@reactos.org> In-Reply-To: <1367525344-7755-3-git-send-email-hpoussin@reactos.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH 2/7] qom: handle registration of new types when initializing the first ones List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: =?UTF-8?B?SGVydsOpIFBvdXNzaW5lYXU=?= Cc: Paolo Bonzini , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, Anthony Liguori Am 02.05.2013 22:08, schrieb Herv=C3=A9 Poussineau: > When initializing all types in object_class_foreach, called by object_c= lass_get_list, > some new types may be registered. Those will change the type internal h= ashtable which > is currently enumerated, and may crash QEMU. >=20 > Fix it, by adding a second hash table which contains all the non-initia= lized types, > merged to the main one before each round of initializations. >=20 > Bug has been detected when registering dynamic types containing an inte= rface. >=20 > Signed-off-by: Herv=C3=A9 Poussineau > --- > qom/object.c | 45 +++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 37 insertions(+), 8 deletions(-) Could you be more specific about how to reproduce the problem? Is it a generic issue or specific to some later patch in this series? I find neither object_class_get_list() nor object_class_for_each() being used in this series. And registering types during object_class_for_each() doesn't sound right... CC'ing Anthony and Paolo. Andreas > diff --git a/qom/object.c b/qom/object.c > index 75e6aac..e0a24dc 100644 > --- a/qom/object.c > +++ b/qom/object.c > @@ -65,25 +65,39 @@ struct TypeImpl > =20 > static Type type_interface; > =20 > +static GHashTable *type_table_to_initialize; > +static GHashTable *type_table_initialized; > + > static GHashTable *type_table_get(void) > { > - static GHashTable *type_table; > - > - if (type_table =3D=3D NULL) { > - type_table =3D g_hash_table_new(g_str_hash, g_str_equal); > + if (!type_table_initialized) { > + type_table_initialized =3D g_hash_table_new(g_str_hash, g_str_= equal); > } > =20 > - return type_table; > + return type_table_initialized; > } > =20 > static void type_table_add(TypeImpl *ti) > { > - g_hash_table_insert(type_table_get(), (void *)ti->name, ti); > + GHashTable **type_table; > + if (ti->class) { > + type_table =3D &type_table_initialized; > + } else { > + type_table =3D &type_table_to_initialize; > + } > + if (!*type_table) { > + *type_table =3D g_hash_table_new(g_str_hash, g_str_equal); > + } > + g_hash_table_insert(*type_table, (void *)ti->name, ti); > } > =20 > static TypeImpl *type_table_lookup(const char *name) > { > - return g_hash_table_lookup(type_table_get(), name); > + TypeImpl *ret =3D g_hash_table_lookup(type_table_get(), name); > + if (!ret && type_table_to_initialize) { > + ret =3D g_hash_table_lookup(type_table_to_initialize, name); > + } > + return ret; > } > =20 > static TypeImpl *type_register_internal(const TypeInfo *info) > @@ -573,13 +587,28 @@ static void object_class_foreach_tramp(gpointer k= ey, gpointer value, > data->fn(k, data->opaque); > } > =20 > +static void object_class_merge(gpointer key, gpointer value, > + gpointer opaque) > +{ > + g_hash_table_insert(type_table_get(), key, value); > +} > + > void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque)= , > const char *implements_type, bool include_ab= stract, > void *opaque) > { > OCFData data =3D { fn, implements_type, include_abstract, opaque }= ; > =20 > - g_hash_table_foreach(type_table_get(), object_class_foreach_tramp,= &data); > + while (type_table_to_initialize && > + g_hash_table_size(type_table_to_initialize) > 0) { > + g_hash_table_foreach(type_table_to_initialize, object_class_me= rge, > + NULL); > + g_hash_table_destroy(type_table_to_initialize); > + type_table_to_initialize =3D NULL; > + > + g_hash_table_foreach(type_table_get(), object_class_foreach_tr= amp, > + &data); > + } > } > =20 > int object_child_foreach(Object *obj, int (*fn)(Object *child, void *o= paque), >=20 --=20 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 N=C3=BCrnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imend=C3=B6rffer; HRB 16746 AG N=C3=BC= rnberg