Re: [reSIProcate] unsafe static Mutex object initialization
I'm not convinced it is safe:
a) you can't be sure about the order that static initialization is done
- some other static initialization code in another translation unit
depending on this static object could execute before it is in a good state
b) although it may not be normal practice within this code, can you be
certain that no other static initializer starts a thread?
On 01/08/11 00:38, Aron Rosenberg wrote:
> I was referring to the ThreadIf stuff as safe since its indirectly only
> initialized during global static initialization. It would unsafe during
> regular runtime as you mentioned.
>
> Aron Rosenberg
> Sr. Director, Engineering,
> LifeSize, a division of Logitech
>
>
>
>
> On Sat, Jul 30, 2011 at 11:15 AM, Byron Campen <bcampen@xxxxxxxxxxxx> wrote:
>
>> Actually, this too can be problematic, because you can get multiple
>> initializations of the Mutex if multiple threads try to construct the same
>> type of object at once. And, if you have any static functions that try to
>> use the mutex, you're sunk because it might not be initialized. A better way
>> to do this is the following:
>>
>> In the header:
>>
>> class FoobaJooba
>> {
>> static Mutex& getMutex()
>> {
>> static Mutex mMutex;
>> return mMutex;
>> }
>>
>> // Nobody should actually touch this, or use it to try to determine
>> // whether the mutex has been initialized; this bool could be anything
>> // during static initialization. It exists solely to cause getMutex()
>> // to be called sometime during static init.
>> static bool ensureInitialized;
>> };
>>
>> In the implementation file:
>>
>> bool FoobaJooba::ensureInitialized=(&initMutex()!=0);
>>
>> This ensures that getMutex() is called sometime during static
>> initialization (it might be called multiple times, but this is ok, since
>> there is only one thread of execution), so multiple init problems don't crop
>> up, and it also ensures that if somebody tries to access the mutex during
>> static init _before_ ensureInitialized has been initialized, the mutex is
>> just initialized a little bit early.
>>
>> Now, this is still not perfect; it doesn't prevent nastiness during static
>> _de_initilization.
>>
>> Best regards,
>> Byron Campen
>>
>>
>> Best regards,
>> Byron Campen
>>
>> The best way to handle this is actually to make the mutex be a static
>> pointer which gets allocated during a class constructor. See ThreadIf class
>> and mTlsDestructorsMutex and friends for the best way to implement this.
>>
>> -Aron
>>
>> Aron Rosenberg
>> LifeSize, a division of Logitech
>>
>>
>> On Thu, Jul 21, 2011 at 11:25 AM, Daniel Pocock <
>> daniel@xxxxxxxxxxxxxxxxxxxxx> wrote:
>>
>>>
>>>
>>>
>>> I notice a few places where a Mutex objected is constructed, typically
>>> as a static member of a class:
>>>
>>> $ grep Mutex rutil/*.hxx | grep static
>>> Log.hxx: static Mutex _mutex;
>>> Random.hxx: static Mutex mMutex;
>>> Time.hxx: static Mutex mWrapCounterMutex;
>>> Time.hxx: static Mutex mMutex;
>>>
>>> The order in which the constructors of these objects are called is
>>> non-deterministic
>>>
>>> It is actually possible that an code section depending on the Mutex
>>> could be attempting to lock on the Mutex before the Mutex itself is
>>> initialized
>>>
>>>
>>>
>>> For UNIX, it may be possible to initialize Mutex::mId =
>>> PTHREAD_MUTEX_INITIALIZER, or even define Mutex like so:
>>>
>>> #define STATIC_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
>>> typedef pthread_mutex_t Mutex;
>>>
>>> and then in some file.cxx:
>>>
>>> Mutex mMutex = STATIC_MUTEX_INIT;
>>>
>>>
>>>
>>> However, the situation for Windows is not quite the same:
>>>
>>> http://locklessinc.com/articles/pthreads_on_windows/
>>>
>>> suggests a hack:
>>>
>>> #define PTHREAD_MUTEX_INITIALIZER {(void*)-1,-1,0,0,0,0}
>>>
>>> that depends on the internal structure of the Windows type
>>> CRITICAL_SECTION
>>>
>>> Has anyone else got any thoughts on this, how it should be done on
>>> Windows, and any other platform considerations that I haven't raised?
>>>
>>>
>>>
>>> _______________________________________________
>>> resiprocate-devel mailing list
>>> resiprocate-devel@xxxxxxxxxxxxxxx
>>> https://list.resiprocate.org/mailman/listinfo/resiprocate-devel
>>>
>>
>> _______________________________________________
>> resiprocate-devel mailing list
>> resiprocate-devel@xxxxxxxxxxxxxxx
>> https://list.resiprocate.org/mailman/listinfo/resiprocate-devel
>>
>>
>>
>