From 0fb210edbfe388ff7f49bf26fca393e6aa549029 Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 30 Jul 2020 19:30:21 +0300 Subject: [PATCH] 0031681: Foundation Classes - Shared Libraries Cannot Be Loaded Standard_ErrorHandler now accesses global mutex via proxy function instead of a global variable to avoid initialization order issues. --- src/Standard/Standard_ErrorHandler.cxx | 30 +++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Standard/Standard_ErrorHandler.cxx b/src/Standard/Standard_ErrorHandler.cxx index 49ac0def03..7129919c4a 100644 --- a/src/Standard/Standard_ErrorHandler.cxx +++ b/src/Standard/Standard_ErrorHandler.cxx @@ -39,10 +39,16 @@ //==== 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() { @@ -64,10 +70,10 @@ Standard_ErrorHandler::Standard_ErrorHandler () : myThread = GetThreadID(); memset (&myLabel, 0, sizeof(myLabel)); - theMutex.Lock(); + GetMutex().Lock(); myPrevious = Top; Top = this; - theMutex.Unlock(); + GetMutex().Unlock(); } @@ -94,7 +100,7 @@ void Standard_ErrorHandler::Destroy() void Standard_ErrorHandler::Unlink() { // put a lock on the stack - theMutex.Lock(); + GetMutex().Lock(); Standard_ErrorHandler* aPrevious = 0; Standard_ErrorHandler* aCurrent = Top; @@ -106,7 +112,7 @@ void Standard_ErrorHandler::Unlink() } if(aCurrent==0) { - theMutex.Unlock(); + GetMutex().Unlock(); return; } @@ -118,7 +124,7 @@ void Standard_ErrorHandler::Unlink() aPrevious->myPrevious=aCurrent->myPrevious; } myPrevious = 0; - theMutex.Unlock(); + GetMutex().Unlock(); // unlink and destroy all registered callbacks Standard_Address aPtr = aCurrent->myCallbackPtr; @@ -217,7 +223,7 @@ Standard_ErrorHandler* Standard_ErrorHandler::FindHandler(const Standard_Handler const Standard_Boolean theUnlink) { // lock the stack - theMutex.Lock(); + GetMutex().Lock(); // Find the current ErrorHandler Accordin tread Standard_ErrorHandler* aPrevious = 0; @@ -262,7 +268,7 @@ Standard_ErrorHandler* Standard_ErrorHandler::FindHandler(const Standard_Handler aStop = Standard_True; } } - theMutex.Unlock(); + GetMutex().Unlock(); return anActive; } @@ -307,4 +313,4 @@ void Standard_ErrorHandler::Callback::UnregisterCallback () ((Standard_ErrorHandler*)myHandler)->myCallbackPtr = (Standard_ErrorHandler::Callback*)myNext; myHandler = myNext = myPrev = 0; } -#endif \ No newline at end of file +#endif -- 2.20.1