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 <k...@codeweavers.com> 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 (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/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to