//==== The top of the Errors Stack ===========================================
static Standard_ErrorHandler* Top = 0;
-// A mutex to protect from concurrent access to Top
-// Note that we should NOT use Sentry while in this class, as Sentry
-// would register mutex as callback in the current exception handler
-static Standard_Mutex theMutex;
+//! A mutex to protect from concurrent access to Top.
+//! Mutex is defined as function to avoid issues caused by
+//! an undefined static variables initialization order across compilation units (@sa #0031681 bug).
+//! Note that we should NOT use Sentry while in this class, as Sentry
+//! would register mutex as callback in the current exception handler.
+static Standard_Mutex& GetMutex()
+{
+ static Standard_Mutex theMutex;
+ return theMutex;
+}
static inline Standard_ThreadId GetThreadID()
{
myThread = GetThreadID();
memset (&myLabel, 0, sizeof(myLabel));
- theMutex.Lock();
+ GetMutex().Lock();
myPrevious = Top;
Top = this;
- theMutex.Unlock();
+ GetMutex().Unlock();
}
void Standard_ErrorHandler::Unlink()
{
// put a lock on the stack
- theMutex.Lock();
+ GetMutex().Lock();
Standard_ErrorHandler* aPrevious = 0;
Standard_ErrorHandler* aCurrent = Top;
}
if(aCurrent==0) {
- theMutex.Unlock();
+ GetMutex().Unlock();
return;
}
aPrevious->myPrevious=aCurrent->myPrevious;
}
myPrevious = 0;
- theMutex.Unlock();
+ GetMutex().Unlock();
// unlink and destroy all registered callbacks
Standard_Address aPtr = aCurrent->myCallbackPtr;
const Standard_Boolean theUnlink)
{
// lock the stack
- theMutex.Lock();
+ GetMutex().Lock();
// Find the current ErrorHandler Accordin tread
Standard_ErrorHandler* aPrevious = 0;
aStop = Standard_True;
}
}
- theMutex.Unlock();
+ GetMutex().Unlock();
return anActive;
}
((Standard_ErrorHandler*)myHandler)->myCallbackPtr = (Standard_ErrorHandler::Callback*)myNext;
myHandler = myNext = myPrev = 0;
}
-#endif
\ No newline at end of file
+#endif