Fix the lock order when sending +initialize, so that we don't hold a lock that

is meant to protect a runtime data structure while trying to acquire a lock
that must be held when running user code that may take an indeterminate amount
of time and may trigger deadlocks.
main
theraven 14 years ago
parent c6eede8179
commit 2d835cffa6

@ -666,14 +666,11 @@ PRIVATE void objc_send_initialize(id object)
objc_send_initialize((id)class->super_class);
}
LOCK(&initialize_lock);
// 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 (objc_test_class_flag(class, objc_class_flag_initialized))
{
UNLOCK(&initialize_lock);
// We know that initialization has started because the flag is set.
// Check that it's finished by grabbing the class lock. This will be
// released once the class has been fully initialized
@ -684,6 +681,11 @@ PRIVATE void objc_send_initialize(id object)
}
LOCK_OBJECT_FOR_SCOPE((id)meta);
LOCK(&initialize_lock);
if (objc_test_class_flag(meta, objc_class_flag_initialized))
{
return;
}
// Set the initialized flag on both this class and its metaclass, to make
// sure that +initialize is only ever sent once.

Loading…
Cancel
Save