Re: User-space threads and NSAutoreleasePool
Re: User-space threads and NSAutoreleasePool
- Subject: Re: User-space threads and NSAutoreleasePool
- From: Manfred Schwind <email@hidden>
- Date: Thu, 18 Mar 2010 11:40:27 +0100
> The problem is that when you call swapcontext() to switch the user-thread
> running on a kernel-thread, the NSAutoreleasePool stack is not swapped out.
> It remains rooted in thread-local storage. As a result, serious problems
> result. Let me give an example.
>
> - (void)doStuff {
> NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
> // do some stuff that calls swapcontext()
> [pool drain];
> }
>
> -doStuff calls swapcontext(), trusting that the other user-thread will
> eventually call swapcontext() and restore the flow to this user-thread.
>
> Further, assume that the second user-thread also allocates an autorelease
> pool before returning. Despite being on separate user-threads, there is
> still only one kernel-thread. Since the autorelease pool stack is in
> (kernel-)thread-local storage, the second user-thread's pool goes on top of
> the same stack:
>
> Autorelease pool stack: pool_from_uthread1 -> pool_from_uthread2
>
> Now, when we swap back to the first user-thread, it will release its
> autorelease pool. This, naturally, releases the second pool as well. When we
> swap back to the second user-thread, anything that was autoreleased is now
> dead and gone.
In my opinion, the only solution is NOT to have any additional Autorelease-Pools "active" when switching the context.
As far as I understand user space contexts, you have total control about when a context switch happens. And you also have total control about your local Autorelease-Pools in your code. So just don't "span" Autorelease-Pools over a context switch:
- (void)doStuff {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
// do some stuff
[pool drain]; // make sure not to have additional Autorelease-Pool
// do some stuff that calls swapcontext()
pool = [[NSAutoreleasePool alloc] init]; // now you can have one again
// do some stuff
[pool drain];
}
Depending on the complexity of your app this may be a bit tricky to find. But "local" Autorelease-Pools are usually kept around small amounts of code. Just don't switch contexts while inside these code areas. ;-)
Regards,
Mani
--
http://mani.de - friendly software
iVolume - listen to music hands-free
LittleSecrets - the encrypted notepad
Sahara - sand in your pocket
Watchdog - baffle the curious
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden