Brian Cole
12/5/2008 3:32:00 PM
On Dec 5, 3:23 am, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.com> wrote:
> On Dec 5, 4:22 am, James Kanze <james.ka...@gmail.com> wrote:
>
>
>
> > On Dec 5, 3:38 am, Brian Cole <col...@gmail.com> wrote:
>
> > > A working draft of theC++standard I was able to obtain says
> > > the following in section 6.7.4:
> > > The zero-initialization(8.5) of alllocalobjects withstatic
> > > storage duration (3.7.1) orthreadstorage duration (3.7.2) is
> > > performed before any otherinitializationtakes place.
> > > First, the only addition for C++0x is thethreadstorage
> > > duration, so I assume the sentence was the following for
> > > previous versions of the standard:
> > > The zero-initialization(8.5) of alllocalobjects withstatic
> > > storage duration (3.7.1) is performed before any other
> > >initializationtakes place.
> > > The criteria "before any otherinitialization" is a little
> > > ambiguous here. Does this mean any otherinitializationinside
> > > thefunctionthestaticresides, or any otherinitialization
> > > the entire program may perform.
>
> > I don't see any ambiguity. "Before any otherinitialization"
> > means "before any otherinitialization".
>
> > Of course, if the compiler can determine that a conformant
> > program cannot see the difference... I rather suspect that no
> > implementation actually initializes thethreadlocalstorage
> > before thethreadusing it is created.
>
> > > Basically, I'm trying to implement something like the
> > > following to allow forthreadsafefunctionlocalstatic
> > >initializationwhile maintaining proper destructor ordering
> > > atexit.
> > > template<class T>
> > > struct Once
> > > {
> > > T *_obj;
> > > long _once;
> > > Once()
> > > {
> > > while (1)
> > > {
> > > long prev = InterlockedCompareExchange(&_once, 1, 0);
> > > if (0 == prev) // got the lock
> > > break;
> > > else if (2 == prev) // The singleton has been initialized.
> > > return _obj;
> > > else {
> > > // Anotherthreadis initializing the singleton: must wait.
> > > assert(1 == prev);
> > > sleep(1); // sleep 1 millisecond
>
> > That's one second, not one millisecond. At least on Posix
> > platforms, and I'm pretty sure Windows as well. (There is no
> >C++standardfunctionsleep.)
>
> There is no "sleep" on Windows. If he meant "Sleep", then it's 1
> millisecond (well, more like 50 or so, realistically, depending on the
> platform).
>
> > > }
> > > }
> > > assert(_obj == 0);
> > > _obj = new T;
> > > InterlockedExchange(&_once, 2);
> > > return _obj;
> > > }
> > > ~Once() { delete _obj; }
> > > inline T& operator *() { return *_obj; }
> > > inline T* operator ->() { return _obj; }
> > > inline operator T* () { return operator ->(); }
> > > };
> > > If I can guarantee that the memory of the object is
> > > zero-initialized during "staticinitialization",
>
> > It will be if the object hasstaticstorage duration. Otherwise
> > not.
>
> > --
> > James Kanze (GABI Software) email:james.ka...@gmail.com
> > Conseils en informatique orientée objet/
> > Beratung in objektorientierter Datenverarbeitung
> > 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
>
>
I did mean millisecond sleep. The code originally called an internal
cross-platform millisecond sleep function. I changed it to just
"sleep" so that everyone else knew the jist of what was going on
there. In fact, there's probably better things to do instead of
"sleep", exponential back-off and such, but this condition is so
rarely encountered it doesn't seem to warrant anything complex.
Thanks for being meticulous though. :-)