From 7af08f5a825b1b66a3bae051febbea99078b794e Mon Sep 17 00:00:00 2001 From: theraven Date: Tue, 24 Nov 2009 13:23:47 +0000 Subject: [PATCH] Tweaked the +initialize order to work around some of the insanity in NSObject and NSAutoreleasePool's interaction in GNUstep. This code is incredibly fragile, and on the old runtime sometimes completely fails and crashes during startup, depending on the order in which the files were linked in -base and how the platform linker works. Hopefully now it should work in all cases. --- sendmsg.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sendmsg.c b/sendmsg.c index 6a9701a..89cd432 100644 --- a/sendmsg.c +++ b/sendmsg.c @@ -415,8 +415,6 @@ __objc_send_initialize (Class class) LOCK(&initialize_lock); if (! CLS_ISRESOLV (class)) __objc_resolve_class_links (); - CLS_SETINITIALIZED (class); - CLS_SETINITIALIZED (class->class_pointer); /* Create the garbage collector type memory description */ @@ -424,6 +422,16 @@ __objc_send_initialize (Class class) if (class->super_class) __objc_send_initialize (class->super_class); + // Superclass +initialize might possibly send a message to this class, in + // which case this method would be called again. See NSObject and + // NSAutoreleasePool +initialize interaction in GNUstep. + if (CLS_ISINITIALIZED (class)) + { + UNLOCK(&initialize_lock); + return; + } + CLS_SETINITIALIZED (class); + CLS_SETINITIALIZED (class->class_pointer); /* Create the dtable, but don't install it on the class quite yet. */ struct sarray *dtable = create_dtable_for_class(class);