AFNetworking/AFNetworking — pull request #2153 by DeeSee (2014-06-25 09:08:56+00:00)
Title: Fix for possible deadlock

The deadlock could be caused due to KVO subscription under the lock. The scenario is as follows:

1. AFURLSessionManager gets a callback and enters critical section with the following stacktrace:
__psynch_mutexwait + 24
_pthread_mutex_lock + 304
-[NSRecursiveLock lock] + 10
-[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] + 114
-[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:context:] + 210
-[AFURLSessionManager removeDelegateForTask:] (AFURLSessionManager.m:365)
-[AFURLSessionManager URLSession:task:didCompleteWithError:] (AFURLSessionManager.m:771)
__55-[__NSCFURLSession delegate_task:didCompleteWithError:]_block_invoke + 48
...

2. Meanwhile, in different thread client code tries to create download task, and client has some KVO subscription/unsubscription in stack frame:
__psynch_mutexwait + 24
_pthread_mutex_lock + 304
-[NSLock lock] + 108
-[AFURLSessionManager setDelegate:forTask:] (AFURLSessionManager.m:355)
-[AFURLSessionManager downloadTaskWithTask:progress:destination:completionHandler:] (AFURLSessionManager.m:561)
-[AFURLSessionManager downloadTaskWithRequest:progress:destination:completionHandler:] (AFURLSessionManager.m:525)
...

....

3. We're in deadlock state: callback thread has acquired AFURLSessionManager's lock and waits for KVO lock, while client code has acquired KVO lock and waits for AFURLSessionManager's lock.

Resolution: you shouldn't put KVO subscription/unsubscription under the lock without good reasoning.