Avoid a deadlock

As described in gnustep/libobjc2#20
main
Niels Grewe 9 years ago
parent 9a2f43ca7d
commit 6b285936be

@ -824,6 +824,13 @@ PRIVATE void objc_send_initialize(id object)
objc_send_initialize((id)class->super_class);
}
// Lock the runtime while we're creating dtables and before we acquire any
// other locks. This prevents a lock-order reversal when
// dtable_for_class is called from something holding the runtime lock while
// we're still holding the initialize lock. We should ensure that we never
// acquire the runtime lock after acquiring the initialize lock.
LOCK_RUNTIME();
// 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.
@ -831,19 +838,17 @@ PRIVATE void objc_send_initialize(id object)
{
// 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
// released once the class has been fully initialized. The runtime
// lock needs to be released first to prevent a deadlock between the
// runtime lock and the class-specific lock.
UNLOCK_RUNTIME();
objc_sync_enter((id)meta);
objc_sync_exit((id)meta);
assert(dtable_for_class(class) != uninstalled_dtable);
return;
}
// Lock the runtime while we're creating dtables and before we acquire any
// other locks. This prevents a lock-order reversal when
// dtable_for_class is called from something holding the runtime lock while
// we're still holding the initialize lock. We should ensure that we never
// acquire the runtime lock after acquiring the initialize lock.
LOCK_RUNTIME();
LOCK_OBJECT_FOR_SCOPE((id)meta);
LOCK(&initialize_lock);
if (objc_test_class_flag(class, objc_class_flag_initialized))

Loading…
Cancel
Save