Re: How to implement readonly property
Re: How to implement readonly property
- Subject: Re: How to implement readonly property
- From: Andreas Grosam <email@hidden>
- Date: Wed, 01 May 2013 10:44:09 +0200
This is a somewhat older but quite interesting thread - nonetheless I felt the final conclusion was still too vague.
So, I did my best to put up a simple "worst case" sample and tried to trick dispatch_once into a race. But I failed. That is, dispatch_once was doing what one would like to expect. While this is eventually no proof, it at least increases the probability that certain use cases are "quite safe", for a given environment.
Maybe someone else will detect a race? Or perhaps, somebody is able to find an even worser worst case? ;)
Note: if a race has been occurred, it would print "x" to stdout.
#include <iostream>
#include <new>
#include <type_traits>
#include <dispatch/dispatch.h>
struct Bar {
void setResult(long value) {
dispatch_once(&_once, ^{
_result = value;
});
}
long getResult() const {
return _result;
}
dispatch_once_t _once;
long _result;
};
int main(int argc, const char * argv[])
{
dispatch_semaphore_t finished_sem = dispatch_semaphore_create(0);
const int N = 1000000;
int n = N;
typedef std::aligned_storage<sizeof(Bar), std::alignment_of<Bar>::value>::type storage_t;
storage_t storage;
while (n) {
//memset(storage, -1, sizeof(storage));
Bar* bar = new (&storage) Bar();
dispatch_async(dispatch_get_global_queue(0, 0), ^{
bar->setResult(n);
dispatch_semaphore_signal(finished_sem);
});
dispatch_semaphore_wait(finished_sem, DISPATCH_TIME_FOREVER);
if (bar->getResult() != n) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
printf("x");
});
}
--n;
}
printf("finished");
return 0;
}
Andreas
On 09.12.2012, at 17:52, Ken Thomases wrote:
> On Dec 9, 2012, at 10:37 AM, Kyle Sluder wrote:
>
>> On Dec 9, 2012, at 6:53 AM, Ken Thomases <email@hidden> wrote:
>>
>>> On Dec 9, 2012, at 1:27 AM, Kyle Sluder wrote:
>>>
>>>> If dispatch_once() really is unsuitable for use with a dispatch_once_t
>>>> stored in Objective-C instance storage, then the correct example in the
>>>> paper I've cited might be a sufficient workaround.
>>>
>>> I thought we had established that, in all sane use cases, an instance variable once predicate is fine.
>>
>> Hence the hedge. ;-)
>>
>>> The cases where an instance variable once predicate would be unsafe are exactly the cases where it would be unsafe to access any instance variable, including the isa pointer. So, if you're using the instance in any way, you've already assumed conditions that make the once predicate fine. (And, hopefully, you've more than assumed it, you've ensured it by proper inter-thread communication of the object pointer.)
>>
>> Yes, but as Greg pointed out the real danger comes from not understanding all the nuances of this, and assuming that dispatch_once is a more powerful synchronization primitive than it really is.
>
> I'm still not understanding the circumspection. The use of dispatch_once() never _contributes_ to unsafe access. It is unsafe if the situation is already unsafe. If you try to avoid using dispatch_once() using other techniques like @synchronized(self), etc., that doesn't help anything.
>
> Intellectually, I understand the concern that people will assume that dispatch_once() introduces safety where it doesn't, but as a practical matter I'm finding it hard to imagine a scenario where a) that comes up or b) avoiding dispatch_once() for some vague (to the naive developer) notion that it's unsafe would lead to better safety. Can you or Greg illustrate with an example?
>
> I feel that dispatch_once() with an instance variable once predicate _is_ the right answer for the class of problems where people would be tempted to use it and that we should be encouraging developers to rely on it rather than invariably worse alternatives.
>
> 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
_______________________________________________
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