fixes for bug #29338

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31188 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2010-08-20 11:07:33 +00:00
parent 752b929b20
commit 37e8986b2c
4 changed files with 276 additions and 121 deletions

View file

@ -858,14 +858,37 @@ safe_remove_from_subclass_list(Class cls)
void
objc_disposeClassPair(Class cls)
{
Class meta = ((id) cls)->isa;
Class meta;
// Remove from the runtime system so nothing tries updating the dtable
// while we are freeing the class.
objc_mutex_lock(__objc_runtime_mutex);
safe_remove_from_subclass_list(meta);
safe_remove_from_subclass_list(cls);
objc_mutex_unlock(__objc_runtime_mutex);
if (cls == 0)
{
return;
}
meta = ((id) cls)->isa;
if (objc_lookUpClass (class_getName (cls)) == (id)cls)
{
fprintf(stderr, "*** ERROR *** function objc_disposeClassPair() called "
"on registered class pair '%s'\n", class_getName(cls));
return;
/*
The runtime provides no mechanism to remove a class.
The following code essentially frees the memory used by a class without
fully removing it ... which obviously tends to cause random crashes
later on if anything tries to use the class or to traverse data
structures containing the class.
Indeed, it's hard to see how this function could ever be made to work
(what if there are subclasses of the class being removed, or if
there are instances of the class?) even with changes to the runtime.
// Remove from the runtime system so nothing tries updating the dtable
// while we are freeing the class.
objc_mutex_lock(__objc_runtime_mutex);
safe_remove_from_subclass_list(meta);
safe_remove_from_subclass_list(cls);
objc_mutex_unlock(__objc_runtime_mutex);
*/
}
// Free the method and ivar lists.
freeMethodLists(cls);
@ -981,9 +1004,28 @@ void __objc_resolve_class_links(void);
void
objc_registerClassPair(Class cls)
{
Class metaClass = cls->class_pointer;
Class metaClass;
Class existing;
if (Nil == cls)
{
fprintf(stderr, "*** ERROR *** function objc_registerClassPair() called "
"on Nil class pair '%s'\n", class_getName(cls));
}
existing = (Class)objc_lookUpClass (class_getName (cls));
if (existing == cls)
{
return; // Already registered
}
if (Nil == existing)
{
fprintf(stderr, "*** ERROR *** function objc_registerClassPair() called "
"for class pair with name ('%s') of existing class.\n",
class_getName(cls));
}
// Initialize the dispatch table for the class and metaclass.
metaClass = cls->class_pointer;
__objc_update_dispatch_table_for_class(metaClass);
__objc_update_dispatch_table_for_class(cls);
__objc_add_class_to_hash(cls);