[cpp-threads] Globals and Threads

Peter Dimov pdimov at mmltd.net
Mon Oct 24 20:51:02 BST 2005


Andrei Alexandrescu wrote:
> Peter Dimov wrote:
>> Peter A. Buhr wrote:
>>
>>>   3. Leave things as they are and allow users to guard things
>>>   manually with a statically-initialized bool:
>>>
>>>   Widget * Foo() {
>>>      static bool initialized = false;
>>>      static Widget result = 0;
>>>      if (std::assign_once(initialized, true)) {
>>>         // Code executed only once
>>>         static Widget w;
>>>         result = &w;
>>>      }
>>>      return result;
>>>   }
>>>
>>>   I incline towards 3 because it's most flexible and doesn't require
>>>   syntax changes.
>>>
>>> I agree with Andrei.
>>
>>
>> Before agreeing, please note that the code above doesn't work.
>
> Look Peter, that's not helpful and just increases traffic on the list.
> If you are referring to my obvious syntax error in result's definition
> line (should be a Widget *, not a Widget), then it would help if you
> said so. If you refer to the fact that I wasn't clear on the semantics
> of assign_once, then saying so would, again, be helpful. If you refer
> to the absence of a memory barrier after result's assignment, then...
> you got my drift. Speak your mind.

Obvious syntax errors don't count, of course, and it's clear what 
assign_once can (or cannot) do.

There is a one race condition and one visibility issue. std::assign_once 
can't postpone the assignment until after w is constructed, because it's a 
function. So another thread may see true, proceed and return 0. And result = 
&w may become visible before w, so it's possible for other threads to 
observe a partially constructed w.

I suppose you could make something along the lines of

if( std::assigner a = std::assign_once( &initialized, true ) )
{
    // ...
}

work... no, not with a bool. Either way, this basically reinvents 
pthread_once. 




More information about the cpp-threads mailing list