From e952d46d0f0101e9a814be6d63af8f108ef45121 Mon Sep 17 00:00:00 2001 From: Paolo Molaro Date: Mon, 26 May 2003 10:24:08 +0000 Subject: [PATCH] Mon May 26 12:10:35 CEST 2003 Paolo Molaro * object.h, object.c: separate vtable creation from type initialization. Make running the .cctor thread safe. svn path=/trunk/mono/; revision=14879 --- mono/metadata/ChangeLog | 6 ++++++ mono/metadata/object.c | 43 +++++++++++++++++++++++++++++++---------- mono/metadata/object.h | 2 +- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index 588eb924528..0339323139b 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,3 +1,9 @@ + +Mon May 26 12:10:35 CEST 2003 Paolo Molaro + + * object.h, object.c: separate vtable creation from type + initialization. Make running the .cctor thread safe. + 2003-05-26 Dietmar Maurer * marshal.c (mono_marshal_get_native_wrapper): free string return values. diff --git a/mono/metadata/object.c b/mono/metadata/object.c index 58ac656c323..e23aa6e9e9d 100644 --- a/mono/metadata/object.c +++ b/mono/metadata/object.c @@ -58,30 +58,55 @@ mono_runtime_object_init (MonoObject *this) /* * mono_runtime_class_init: - * @klass: klass that needs to be initialized + * @vtable: vtable that needs to be initialized * - * This routine calls the class constructor for @class. + * This routine calls the class constructor for @vtable. */ void -mono_runtime_class_init (MonoClass *klass) +mono_runtime_class_init (MonoVTable *vtable) { int i; - MonoException *exc = NULL; + MonoException *exc; MonoException *exc_to_throw; MonoMethod *method; + MonoClass *klass; gchar *full_name; + gboolean found; + + MONO_ARCH_SAVE_REGS; + + if (vtable->initialized || vtable->initializing) + return; + exc = NULL; + found = FALSE; + klass = vtable->klass; + for (i = 0; i < klass->method.count; ++i) { method = klass->methods [i]; if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) && (strcmp (".cctor", method->name) == 0)) { - mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc); - if (exc != NULL) - break; - return; + found = TRUE; + break; } } + if (found) { + mono_domain_lock (vtable->domain); + /* double check... */ + if (vtable->initialized || vtable->initializing) + return; + vtable->initializing = 1; + mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc); + vtable->initialized = 1; + vtable->initializing = 0; + /* FIXME: if the cctor fails, the type must be marked as unusable */ + mono_domain_unlock (vtable->domain); + } else { + vtable->initialized = 1; + return; + } + if (exc == NULL || (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System") && @@ -486,8 +511,6 @@ mono_class_vtable (MonoDomain *domain, MonoClass *class) if (class->parent) mono_class_vtable (domain, class->parent); - mono_runtime_class_init (class); - if (class->contextbound) vt->remote = 1; else diff --git a/mono/metadata/object.h b/mono/metadata/object.h index d6829568357..388e079ad82 100644 --- a/mono/metadata/object.h +++ b/mono/metadata/object.h @@ -303,7 +303,7 @@ void mono_runtime_object_init (MonoObject *this_obj); void -mono_runtime_class_init (MonoClass *klass); +mono_runtime_class_init (MonoVTable *vtable); void mono_install_runtime_invoke (MonoInvokeFunc func); -- 2.25.1