Here is a StaticCriticalSection object. It functions as a static/global CriticalSection, but one that is guaranteed to be in a correct initialized state before any code runs, including constructors for other objects with static storage duration (i.e. global class objects). Usage example at the bottom:
REMOVED AND REPLACED BY A MORE GENERIC CLASS THAT WORKS FOR ANY OBJECT
Here:
http://rawmaterialsoftware.com/viewtopic.php?f=6&t=6995
Could you maybe give an example when using a normal CriticalSection as static variable would not work? I’ve done that quite a lot in my code, but never have had any problems (until now!).
Two cases:
- CriticalSection at function scope with static storage duration. Example:
void calledFromMultipleThreads ()
{
static CriticalSection mutex;
// Race condition causes double initializion with some build environments
CriticalSection::ScopedLockType lock (mutex);
}
- CriticalSection at file scope with static storage duration, accessed from a constructor of an object at file scope with static storage duration. Example:
//foo.cpp
CriticalSection globalMutex;
//bar.cpp
extern CriticalSection globalMutex;
struct Singleton {
Singleton ()
{
CriticalSection::ScopedLockType lock (globalMutex);
// Will fail if we execute before globalLock constructor
}
};
Singleton globalSingleton; // Will fail depending on order of constructors
StaticCriticalSection solves both cases. In c++0x condition #1 is fixed (but #2 is still a problem).
namespace { struct PrivateTag { }; } // distinguishes the StaticCriticalSection
void safelyCalledFromMultipleThreads ()
{
StaticCriticalSection <PrivateTag> mutex;
StaticCriticalSection <PrivateTag>::ScopedLockType lock (mutex);
// Works correctly when called from multiple threads
}
and
//common.h
struct GlobalMutexTag { };
//foo.cpp
StaticCriticalSection <GlobalMutexTag> globalMutex;
//bar.cpp
extern StaticCriticalSection <GlobalMutexTag> globalMutex;
struct Singleton
{
Singleton ()
{
StaticCriticalSection <GlobalMutexTag>::ScopedLockType lock (globalMutex);
// Works no matter what the order of construction
}
};
Singleton globalSingleton; // Always constructs properly no matter what the order
Did you really discover a problem or do you think you have an issue only because of what I exposed regarding function level statics?
No, I never had any problems at all with static CriticalSection so far. But it’s nice to know that there could be some potential problems.