Merge pull request #21 from ngrewe/deadlock

Avoid deadlock in objc_send_initialize()
main
davidchisnall 9 years ago committed by GitHub
commit 4afd2d4241

@ -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