Re: Lockless thread-safe accessor using blocks: how to?
Re: Lockless thread-safe accessor using blocks: how to?
- Subject: Re: Lockless thread-safe accessor using blocks: how to?
- From: Jason Harris <email@hidden>
- Date: Thu, 14 Apr 2011 23:40:37 +0200
On Apr 14, 2011, at 7:44 PM, David Duncan wrote:
> On Apr 14, 2011, at 10:26 AM, WT wrote:
>
>> On Apr 14, 2011, at 2:09 PM, David Duncan wrote:
>>
>>> On Apr 14, 2011, at 10:02 AM, WT wrote:
>>>
>>>> I looked at dispatch_once() at one point, but I'm still confused by how it works.
>>>
>>> dispatch_once uses a predicate (just a flag) to determine if it should run the block or not. If that flag is false, then it sets the flag to true and executes the block. If the flag is true, it does nothing. What makes dispatch_once useful over a simple if statement is that it ensures that if you execute dispatch_once concurrently from multiple threads that flag gets updated exactly once, and the block gets called exactly once.
>>
>> Thanks for explaining it, David. The bit that was throwing me off is the predicate part. I understand now that all I need is to declare a static variable of the appropriate type and pass a pointer to it to dispatch_once().
>
> The lifetime of the predicate needs to match that of the initialization done by the block. If the block's initialization is done for an instance variable, then the predicate should also be an instance variable. If the initialization is for a global, the predicate should also be a global.
So I just want to confirm this... Are you saying that one can do something like:
@interface MyObject
{
dispatch_once_t initilizeComputedResource;
ComputedResource* theResource;
}
- (ComputedResource*) resource;
@end
@implementation MyObject
- (ComputedResource*) resource
{
dispatch_once(&initilizeComputedResource, ^{
theResource = [self doSomeBigComputation];
});
return theResource;
}
@end
and later I can call
{
MyObject* anObject = [[MyObject alloc]init];
ComputedResource* r = [anObject resource];
[r doSomething];
}
and its legal? (I have GC switched on)
Looking at http://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/c/func/dispatch_once
and the bit where it says:
"The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage is undefined."
Seemed to me to indicate that it wasn't valid to have the kind of code I have above... I would like to use the code I have above so I can ensure something is run *once* for a given object. (Otherwise of course I just fall back on @synchronized but thats longer and not as fast...)
Thanks,
Jason
_______________________________________________
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