Refactor locking in setSuperclass.
Now all lock ownership is tied to scopes, so will be released correctly
in all return paths.
@@ -522,19 +522,19 @@ Class class_setSuperclass(Class cls, Class newSuper)
{
CHECK_ARG(cls);
CHECK_ARG(newSuper);
+ Class oldSuper;
if (Nil == cls) { return Nil; }
- LOCK_RUNTIME();
+ {
+ LOCK_RUNTIME_FOR_SCOPE();
- if (cls->super_class == newSuper) {
- UNLOCK_RUNTIME();
- return newSuper;
- }
+ oldSuper = cls->super_class;
+
+ if (oldSuper == newSuper) { return newSuper; }
safe_remove_from_subclass_list(cls);
objc_resolve_class(newSuper);
- Class oldSuper = cls->super_class;
cls->super_class = newSuper;
// The super class's subclass list is used in certain method resolution scenarios.
@@ -561,18 +561,14 @@ Class class_setSuperclass(Class cls, Class newSuper)
newSuperMeta->subclass_list = meta;
}
- LOCK(&initialize_lock);
+ LOCK_FOR_SCOPE(&initialize_lock);
if (!objc_test_class_flag(cls, objc_class_flag_initialized))
{
// Uninitialized classes don't have dtables to update
// and don't need their superclasses initialized.
- UNLOCK(&initialize_lock);
- UNLOCK_RUNTIME();
return oldSuper;
}
-
- UNLOCK(&initialize_lock);
- UNLOCK_RUNTIME();
+ }
objc_send_initialize((id)newSuper); // also initializes the metaclass
objc_update_dtable_for_new_superclass(cls->isa, newSuper->isa);
