I forgot to zero out the variable after cache is handed to the current autorelease pool (after objc_autorelease(objc_retain(_cache));) so it did not work.
On Oct 23, 2013, at 16:07, Andreas Grosam <agro...@onlinehome.de> wrote: > You may try the following, which is probably a hack: > > In the dealloc method of the Database, do something like this: > > - (void) dealloc { > NSCache* cache = self.cache; > dispatch_async(private_queue, ^{ > cache = nil; > }); > } > > Now, if `cache_remove_with_block` executes on a different thread than where > the block `cache = nil;` executes, respectively, if it starts executing when > `cache_remove_with_block` already has been finished, then the dead lock might > get resolved. > > > Andreas > > > On 21.10.2013, at 21:11, Jens Alfke <j...@mooseyard.com> wrote: > >> I’ve just gotten a nasty bug report involving an iOS app hanging when it >> goes into the background. The problem is a deadlock involving NSCache. I can >> see what the problem is, but I don’t know what to do about it. >> >> In a nutshell: An NSCache is evicting objects, and as a result of that its >> last reference goes away so the cache gets dealloced. Only the dealloc >> method needs the same (non-recursive) lock the eviction call is using, so it >> deadlocks. >> >> Specifically, there is a “database” object that has a strong reference to an >> NSCache which maps to various ‘document’ objects (indexed by key.) The >> document objects have strong references back to the database. >> >> In the situation that hangs, there is a database with one document, neither >> of which have any external strong references to them. (They probably used to >> at one point, but the app stopped using that database.) That’s fine, it’s >> not a reference cycle because the NSCache will get cleaned up. Only the >> cleanup doesn’t work because: >> >> 1. OS tells NSCache to flush value objects (`cache_remove_with_block`) >> 2. NSCache releases the document, causing it to be dealloced >> 3. Document’s dealloc implicitly releases its reference to the database >> 4. Database is released and dealloced, implicitly releasing the NSCache >> 5. NSCache is dealloced … but the `cache_destroy` call needs the mutex >> that’s already being held by `cache_remove_with_block`. >> >> (You can see the full backtrace in the bug report on github.) >> >> Has anyone else run into this? Is there a workaround? This has come up once >> before for me, and I was able to work around it by making the cache-owner >> object call -autorelease instead of -release on the NSCache, to defer the >> call to the cache’s dealloc. But I’m now using ARC so that isn’t an option. >> >> —Jens >> _______________________________________________ >> >> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) >> >> Please do not post admin requests or moderator comments to the list. >> Contact the moderators at cocoa-dev-admins(at)lists.apple.com >> >> Help/Unsubscribe/Update your Subscription: >> https://lists.apple.com/mailman/options/cocoa-dev/agrosam%40onlinehome.de >> >> This email sent to agro...@onlinehome.de > > > _______________________________________________ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/xcvista%40me.com > > This email sent to xcvi...@me.com
signature.asc
Description: Message signed with OpenPGP using GPGMail
_______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com