Re: init (via ctor) of function local static var : not thread safe ????
Giovanni,
Thanks for your help and comments. But the problem is, that this does not
solve the race condition.
Then, assuming that you have Foo defined somewhere, you can associate a
critical section to it:
Foo foo;
CriticalSection csFoo;
as i wrote, there is just one Foo in my query function:
Foo & get_a_foo()
{
static Foo aFoo;
return aFoo;
}
so, what should i do?
Foo & get_a_Foo()
{
static CriticalSection csFoo;
static Foo aFoo;
return aFoo;
}
this just moves the problem to the constructor of csFoo.
thread1 enter get_a_foo. sees csFoo_isInitialized as false and (done by the
compiler) sets csFoo_isInitialized to true.
threadswitch
thread2 enter get_a_foo : now sees csFoo_isInitialized is true and uses an
not initialized CriticalSection.
but i found a solution in the meantime. i remembered this not interruptable
"lock: xchg long,long" X86 statement and that there is
even a windows wrapper for it:
#define __lxchg(a,b) (int)InterlockedExchange((long*)a, (long)b) // ATOMIC
!!!
static Foo & get_a_foo()
{
static unsigned long mLock = 0;
while (__lxchg(&mLock,1)!=0)
{
::Sleep(1);
}
static Foo aFoo;
__lxchg(&mLock,0);
return aFoo;
}
the advantage of this solution is, that mLock is initialized by the compiler
by placeing it in the correct data segment at the moment when the binary is
loaded.
there is no constructor call required. and now since __lxchg() is atomic
there can be no race condition anymore.
One Note:
placeing
static Foo aFoo;
(or static CriticalSection aCriticalSection) at global scope would fix the
race condition problem, because global variables were initialized when
DLL_initTerm is executed (single threaded) but results in another problem :
=== file1.cpp ===
static Foo aFoo;
Foo & get_a_Foo()
{
return aFoo;
}
===============
===== file2.cpp ===
somethingelseType xxxc = get_a_Foo().querySomethingElse();
===============
now, when the global ctor code first exectutes the ctors in file2.cpp then
get_a_foo() returns an allocated, but not initialized aFoo.... (this was my
original problem!).
thx
mario.