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: Ken Thomases <email@hidden>
- Date: Thu, 14 Apr 2011 21:43:42 -0500
On Apr 14, 2011, at 4:40 PM, Jason Harris wrote:
> On Apr 14, 2011, at 7:44 PM, David Duncan wrote:
>
>> 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)
Yes, that's legal and should work.
> 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...)
I think that note in the documentation is overzealous. The requirements are that the predicate storage must exist _and be initialized to zero_ prior to any call to dispatch_once using it and persist until after all calls to dispatch_once using it have completed. Obviously, any calls to dispatch_once which are meant to protect the same thing must use the same predicate storage. An instance variable predicate protecting the initialization of another instance variable satisfies those requirements in any sane scenario (where you've ensured that no method of the instance is in-progress on any thread when the instance is deallocated).
Regards,
Ken
_______________________________________________
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