|Subject:||Deadlock in NSUserDefaults|
|Date:||Fri, 6 Jun 2008 18:12:22 -0400|
Here's a timeline. Line numbers refer to NSUserDefaults.m in gnustep- base 1.13.0 (although a quick glance at 1.14.1 leads me to believe it still has the same bug). All of the instance methods are being called on the same instance, the default NSUserDefaults object.
thread 1 calls -[NSUserDefaults synchronize], which acquires _lock (line 1588) and calls -[NSUserDefaults writeDefaults] thread 1 -[NSUserDefaults writeDefaults] calls -[NSDictionary writeToFile:atomically:] thread 2 calls NSLog, which calls NSCalendarDate, which calls GSUserDefaultsDictionaryRepresentation thread 2 GSUserDefaultsDictionaryRepresentation acquires classLock (line 1968) thread 1 -[NSDictionary writeToFile:atomically:] calls GSUserDefaultsDictionaryRepresentation thread 1 GSUserDefaultsDictionaryRepresentation attempts to acquire classLock (line 1968) and hangs because thread 2 has it thread 2 GSUserDefaultsDictionaryRepresentation calls -[NSUserDefaults dictionaryRepresentation] thread 2 -[NSUserDefaults dictionaryRepresentation] attempts to acquire _lock (line 1765) and hangs because thread 1 has it
This is a classic lock ordering bug. One simple way to avoid it it to always follow the rule that whenever multiple locks are acquired, they must be acquired in the same order, and released in the reverse order. However, at first glance, it looks to me like making NSUserDefaults.m conform to this rule might require major surgery.
|[Prev in Thread]||Current Thread||[Next in Thread]|