From: Pasukhin Dmitry Date: Mon, 3 Nov 2025 16:44:08 +0000 (+0000) Subject: Coding - Replace Standard_Mutex with std::mutex and migrate to RAII locks (#766) X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=787bee375c628620fdc72b0c6b723cbab3e46f3c;p=occt.git Coding - Replace Standard_Mutex with std::mutex and migrate to RAII locks (#766) - Replace legacy Standard_Mutex usage across many modules with std::mutex. - Include where needed and remove includes. - Replace Standard_Mutex::Sentry / explicit Lock/Unlock with std::lock_guard or std::unique_lock. - Convert optional/heap mutex holders to std::unique_ptr and adapt locking accordingly. - Simplify several singleton initializations (remove manual double-checked locking where safe). - Use thread_local for per-thread flags instead of ad-hoc mutex protection. - Fix BVH_BuildQueue Fetch logic to preserve thread counters and wasBusy handling. - Remove obsolete TopTools_MutexForShapeProvider sources and update FILES.cmake. This modernizes mutex usage, reduces dependency on custom mutex types and improves clarity of locking patterns. --- diff --git a/src/ApplicationFramework/TKCDF/CDF/CDF_StoreList.cxx b/src/ApplicationFramework/TKCDF/CDF/CDF_StoreList.cxx index 55279c6aa2..0dd24bbdb1 100644 --- a/src/ApplicationFramework/TKCDF/CDF/CDF_StoreList.cxx +++ b/src/ApplicationFramework/TKCDF/CDF/CDF_StoreList.cxx @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/src/ApplicationFramework/TKLCAF/TDF/TDF_DerivedAttribute.cxx b/src/ApplicationFramework/TKLCAF/TDF/TDF_DerivedAttribute.cxx index 9c12472df1..3370dc7cb7 100644 --- a/src/ApplicationFramework/TKLCAF/TDF/TDF_DerivedAttribute.cxx +++ b/src/ApplicationFramework/TKLCAF/TDF/TDF_DerivedAttribute.cxx @@ -14,10 +14,11 @@ #include #include -#include #include #include +#include + namespace TDF_DerivedAttributeGlobals { @@ -55,9 +56,9 @@ static NCollection_DataMap aLock(TDF_DerivedAttributeGlobals::Mutex()); TDF_DerivedAttributeGlobals::Creators().Append(aData); return theNewAttributeFunction; } @@ -127,7 +128,7 @@ static void Initialize() Handle(TDF_Attribute) TDF_DerivedAttribute::Attribute(Standard_CString theType) { - Standard_Mutex::Sentry aSentry(TDF_DerivedAttributeGlobals::Mutex()); + std::lock_guard aLock(TDF_DerivedAttributeGlobals::Mutex()); Initialize(); if (const Handle(TDF_Attribute)* aResult = TDF_DerivedAttributeGlobals::Attributes().Seek(theType)) @@ -143,7 +144,7 @@ Handle(TDF_Attribute) TDF_DerivedAttribute::Attribute(Standard_CString theType) const TCollection_AsciiString& TDF_DerivedAttribute::TypeName(Standard_CString theType) { - Standard_Mutex::Sentry aSentry(TDF_DerivedAttributeGlobals::Mutex()); + std::lock_guard aLock(TDF_DerivedAttributeGlobals::Mutex()); Initialize(); if (TCollection_AsciiString* const* aResult = TDF_DerivedAttributeGlobals::Types().Seek(theType)) { @@ -157,7 +158,7 @@ const TCollection_AsciiString& TDF_DerivedAttribute::TypeName(Standard_CString t void TDF_DerivedAttribute::Attributes(NCollection_List& theList) { - Standard_Mutex::Sentry aSentry(TDF_DerivedAttributeGlobals::Mutex()); + std::lock_guard aLock(TDF_DerivedAttributeGlobals::Mutex()); Initialize(); NCollection_DataMap::Iterator anAttrIter; diff --git a/src/DataExchange/TKDE/DE/DE_ConfigurationNode.cxx b/src/DataExchange/TKDE/DE/DE_ConfigurationNode.cxx index f3b8340238..ac847436da 100644 --- a/src/DataExchange/TKDE/DE/DE_ConfigurationNode.cxx +++ b/src/DataExchange/TKDE/DE/DE_ConfigurationNode.cxx @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/src/DataExchange/TKDE/DE/DE_PluginHolder.hxx b/src/DataExchange/TKDE/DE/DE_PluginHolder.hxx index c70ae9f285..45a93f1e49 100644 --- a/src/DataExchange/TKDE/DE/DE_PluginHolder.hxx +++ b/src/DataExchange/TKDE/DE/DE_PluginHolder.hxx @@ -15,6 +15,8 @@ #define _DE_PluginHolder_HeaderFile #include + +#include #include //! Base class to work with DE_Wrapper global registration of components. @@ -28,14 +30,14 @@ class DE_PluginHolder public: DE_PluginHolder() { - Standard_Mutex::Sentry aLock(DE_Wrapper::GlobalLoadMutex()); + std::lock_guard aLock(DE_Wrapper::GlobalLoadMutex()); myInternalConfiguration = new TheConfType; myInternalConfiguration->Register(DE_Wrapper::GlobalWrapper()); } ~DE_PluginHolder() { - Standard_Mutex::Sentry aLock(DE_Wrapper::GlobalLoadMutex()); + std::lock_guard aLock(DE_Wrapper::GlobalLoadMutex()); myInternalConfiguration->UnRegister(DE_Wrapper::GlobalWrapper()); } diff --git a/src/DataExchange/TKDE/DE/DE_Wrapper.cxx b/src/DataExchange/TKDE/DE/DE_Wrapper.cxx index 78997b5628..5ec7122efa 100644 --- a/src/DataExchange/TKDE/DE/DE_Wrapper.cxx +++ b/src/DataExchange/TKDE/DE/DE_Wrapper.cxx @@ -91,9 +91,9 @@ void DE_Wrapper::SetGlobalWrapper(const Handle(DE_Wrapper)& theWrapper) //================================================================================================= -Standard_Mutex& DE_Wrapper::GlobalLoadMutex() +std::mutex& DE_Wrapper::GlobalLoadMutex() { - static Standard_Mutex THE_GLOBAL_LOAD_MUTEX; + static std::mutex THE_GLOBAL_LOAD_MUTEX; return THE_GLOBAL_LOAD_MUTEX; } diff --git a/src/DataExchange/TKDE/DE/DE_Wrapper.hxx b/src/DataExchange/TKDE/DE/DE_Wrapper.hxx index a159adbe8d..e29c3db8ff 100644 --- a/src/DataExchange/TKDE/DE/DE_Wrapper.hxx +++ b/src/DataExchange/TKDE/DE/DE_Wrapper.hxx @@ -19,9 +19,10 @@ #include #include #include -#include #include +#include + class TopoDS_Shape; class XSControl_WorkSession; class TDocStd_Document; @@ -73,7 +74,7 @@ public: //! @param[in] theWrapper object to set as global configuration Standard_EXPORT static void SetGlobalWrapper(const Handle(DE_Wrapper)& theWrapper); - Standard_EXPORT static Standard_Mutex& GlobalLoadMutex(); + Standard_EXPORT static std::mutex& GlobalLoadMutex(); public: //! Reads a CAD file, according internal configuration diff --git a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafReader.cxx b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafReader.cxx index 8e16905504..7b7bafd42a 100644 --- a/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafReader.cxx +++ b/src/DataExchange/TKDEGLTF/RWGltf/RWGltf_CafReader.cxx @@ -67,7 +67,7 @@ public: } if (myThreadPool.HasThreads()) { - Standard_Mutex::Sentry aLock(&myMutex); + std::lock_guard aLock(myMutex); myProgress.Next(); } else @@ -84,7 +84,7 @@ protected: protected: NCollection_Vector* myFaceList; - mutable Standard_Mutex myMutex; + mutable std::mutex myMutex; mutable Message_ProgressScope myProgress; const OSD_ThreadPool::Launcher& myThreadPool; }; diff --git a/src/DataExchange/TKDESTEP/STEPCAFControl/STEPCAFControl_Controller.cxx b/src/DataExchange/TKDESTEP/STEPCAFControl/STEPCAFControl_Controller.cxx index 3ea71d9fcd..c35638a7ef 100644 --- a/src/DataExchange/TKDESTEP/STEPCAFControl/STEPCAFControl_Controller.cxx +++ b/src/DataExchange/TKDESTEP/STEPCAFControl/STEPCAFControl_Controller.cxx @@ -19,6 +19,8 @@ #include #include +#include + IMPLEMENT_STANDARD_RTTIEXT(STEPCAFControl_Controller, STEPControl_Controller) //================================================================================================= @@ -33,9 +35,9 @@ STEPCAFControl_Controller::STEPCAFControl_Controller() Standard_Boolean STEPCAFControl_Controller::Init() { - static Standard_Mutex theMutex; + static std::mutex aMutex; + std::lock_guard aLock(aMutex); { - Standard_Mutex::Sentry aSentry(theMutex); static Standard_Boolean inic = Standard_False; if (inic) return Standard_True; diff --git a/src/DataExchange/TKDESTEP/STEPControl/STEPControl_Controller.cxx b/src/DataExchange/TKDESTEP/STEPControl/STEPControl_Controller.cxx index 57827135c8..f4f00372f8 100644 --- a/src/DataExchange/TKDESTEP/STEPControl/STEPControl_Controller.cxx +++ b/src/DataExchange/TKDESTEP/STEPControl/STEPControl_Controller.cxx @@ -49,15 +49,17 @@ #include #include +#include + IMPLEMENT_STANDARD_RTTIEXT(STEPControl_Controller, XSControl_Controller) // Pour NewModel et Write : definition de produit (temporaire ...) STEPControl_Controller::STEPControl_Controller() : XSControl_Controller("STEP", "step") { - static Standard_Boolean init = Standard_False; - static Standard_Mutex aMutex; - aMutex.Lock(); + static Standard_Boolean init = Standard_False; + static std::mutex aMutex; + std::lock_guard aLock(aMutex); if (!init) { RWHeaderSection::Init(); @@ -338,7 +340,6 @@ STEPControl_Controller::STEPControl_Controller() init = Standard_True; } - aMutex.Unlock(); Handle(STEPControl_ActorWrite) ActWrite = new STEPControl_ActorWrite; myAdaptorWrite = ActWrite; diff --git a/src/DataExchange/TKDESTEP/STEPControl/STEPControl_Reader.cxx b/src/DataExchange/TKDESTEP/STEPControl/STEPControl_Reader.cxx index d0df52564d..387fe3a295 100644 --- a/src/DataExchange/TKDESTEP/STEPControl/STEPControl_Reader.cxx +++ b/src/DataExchange/TKDESTEP/STEPControl/STEPControl_Reader.cxx @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include diff --git a/src/DataExchange/TKDESTEP/STEPEdit/STEPEdit.cxx b/src/DataExchange/TKDESTEP/STEPEdit/STEPEdit.cxx index ac875950b3..fbe8802cb6 100644 --- a/src/DataExchange/TKDESTEP/STEPEdit/STEPEdit.cxx +++ b/src/DataExchange/TKDESTEP/STEPEdit/STEPEdit.cxx @@ -16,12 +16,13 @@ #include #include #include -#include #include #include #include #include +#include + Handle(Interface_Protocol) STEPEdit::Protocol() { /* @@ -44,8 +45,8 @@ Handle(StepData_StepModel) STEPEdit::NewModel() Handle(IFSelect_Signature) STEPEdit::SignType() { - static Standard_Mutex aMutex; - Standard_Mutex::Sentry aSentry(aMutex); + static std::mutex aMutex; + std::lock_guard aLock(aMutex); static Handle(StepSelect_StepType) sty; if (!sty.IsNull()) return sty; diff --git a/src/DataExchange/TKDESTEP/STEPSelections/STEPSelections_SelectGSCurves.cxx b/src/DataExchange/TKDESTEP/STEPSelections/STEPSelections_SelectGSCurves.cxx index e25326ad3e..d3f8166001 100644 --- a/src/DataExchange/TKDESTEP/STEPSelections/STEPSelections_SelectGSCurves.cxx +++ b/src/DataExchange/TKDESTEP/STEPSelections/STEPSelections_SelectGSCurves.cxx @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -28,7 +27,10 @@ IMPLEMENT_STANDARD_RTTIEXT(STEPSelections_SelectGSCurves, IFSelect_SelectExplore) -static Standard_Integer flag; +namespace +{ +thread_local Standard_Integer flag; +} // namespace STEPSelections_SelectGSCurves::STEPSelections_SelectGSCurves() : IFSelect_SelectExplore(-1) @@ -53,14 +55,11 @@ Standard_Boolean STEPSelections_SelectGSCurves::Explore(const Standard_Integer / for (subs.Start(); subs.More() && !isInGeomSet; subs.Next()) if (subs.Value()->IsKind(STANDARD_TYPE(StepShape_GeometricSet))) { - static Standard_Mutex aMutex; - aMutex.Lock(); if (flag) { explored.AddItem(subs.Value()); flag = 0; } - aMutex.Unlock(); isInGeomSet = Standard_True; } if (isInGeomSet) diff --git a/src/DataExchange/TKDESTEP/STEPSelections/STEPSelections_SelectInstances.cxx b/src/DataExchange/TKDESTEP/STEPSelections/STEPSelections_SelectInstances.cxx index df54809a42..a90bad1cb7 100644 --- a/src/DataExchange/TKDESTEP/STEPSelections/STEPSelections_SelectInstances.cxx +++ b/src/DataExchange/TKDESTEP/STEPSelections/STEPSelections_SelectInstances.cxx @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -40,8 +39,11 @@ IMPLEMENT_STANDARD_RTTIEXT(STEPSelections_SelectInstances, IFSelect_SelectExplore) -static Handle(Interface_HGraph) myGraph; -static Interface_EntityIterator myEntities; +namespace +{ +thread_local Handle(Interface_HGraph) myGraph; +thread_local Interface_EntityIterator myEntities; +} // namespace STEPSelections_SelectInstances::STEPSelections_SelectInstances() : IFSelect_SelectExplore(-1) @@ -153,8 +155,6 @@ static void AddInstances(const Handle(Standard_Transient)& start, Interface_EntityIterator STEPSelections_SelectInstances::RootResult(const Interface_Graph& G) const { - static Standard_Mutex aMutex; - Standard_Mutex::Sentry aSentry(aMutex); if (myGraph.IsNull() || (G.Model() != myGraph->Graph().Model())) { Interface_EntityIterator roots = G.RootEntities(); diff --git a/src/DataExchange/TKDESTEP/StepFile/StepFile_Read.cxx b/src/DataExchange/TKDESTEP/StepFile/StepFile_Read.cxx index 83a7ed9a8a..cd2f52d73b 100644 --- a/src/DataExchange/TKDESTEP/StepFile/StepFile_Read.cxx +++ b/src/DataExchange/TKDESTEP/StepFile/StepFile_Read.cxx @@ -31,7 +31,6 @@ #include #include -#include #include #include @@ -42,6 +41,7 @@ #include "step.tab.hxx" #include +#include #ifdef OCCT_DEBUG #define CHRONOMESURE @@ -49,8 +49,12 @@ namespace { -static Standard_Mutex THE_GLOBAL_READ_MUTEX; +static std::mutex& GetGlobalReadMutex() +{ + static std::mutex THE_GLOBAL_READ_MUTEX; + return THE_GLOBAL_READ_MUTEX; } +} // namespace void StepFile_Interrupt(Standard_CString theErrorMessage, const Standard_Boolean theIsFail) { @@ -119,8 +123,9 @@ static Standard_Integer StepFile_Read(const char* the sout << " ... STEP File Read ...\n"; - Standard_Mutex::Sentry aLocker(THE_GLOBAL_READ_MUTEX); - Standard_Integer nbhead, nbrec, nbpar; + std::lock_guard aLock(GetGlobalReadMutex()); + + Standard_Integer nbhead, nbrec, nbpar; aFileDataModel.GetFileNbR(&nbhead, &nbrec, &nbpar); // renvoi par lex/yacc Handle(StepData_StepReaderData) undirec = // clang-format off diff --git a/src/DataExchange/TKDESTEP/StepSelect/StepSelect_StepType.cxx b/src/DataExchange/TKDESTEP/StepSelect/StepSelect_StepType.cxx index 0f25016874..5ee44da6d8 100644 --- a/src/DataExchange/TKDESTEP/StepSelect/StepSelect_StepType.cxx +++ b/src/DataExchange/TKDESTEP/StepSelect/StepSelect_StepType.cxx @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/src/DataExchange/TKDESTEP/StepToTopoDS/StepToTopoDS_TranslateEdgeLoop.cxx b/src/DataExchange/TKDESTEP/StepToTopoDS/StepToTopoDS_TranslateEdgeLoop.cxx index 04d6130c23..62865d7e99 100644 --- a/src/DataExchange/TKDESTEP/StepToTopoDS/StepToTopoDS_TranslateEdgeLoop.cxx +++ b/src/DataExchange/TKDESTEP/StepToTopoDS/StepToTopoDS_TranslateEdgeLoop.cxx @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Scene.cxx b/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Scene.cxx index 0f7be1897e..182015177b 100644 --- a/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Scene.cxx +++ b/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Scene.cxx @@ -83,7 +83,7 @@ const Handle(VrmlData_Node)& VrmlData_Scene::AddNode(const Handle(VrmlData_Node) if (theN.IsNull() == Standard_False) if (theN->IsKind(STANDARD_TYPE(VrmlData_WorldInfo)) == Standard_False) { - myMutex.Lock(); + std::lock_guard aLock(myMutex); const Handle(VrmlData_Node)& aNode = myAllNodes.Append((&theN->Scene() == this) ? theN : theN->Clone(NULL)); // Name is checked for uniqueness. If not, letter 'D' is appended until @@ -93,7 +93,6 @@ const Handle(VrmlData_Node)& VrmlData_Scene::AddNode(const Handle(VrmlData_Node) aNode->setName(aNode->Name(), "D"); if (isTopLevel) myLstNodes.Append(aNode); - myMutex.Unlock(); return aNode; } static Handle(VrmlData_Node) aNullNode; @@ -108,8 +107,8 @@ const Handle(VrmlData_Node)& VrmlData_Scene::AddNode(const Handle(VrmlData_Node) Standard_OStream& operator<<(Standard_OStream& theOutput, const VrmlData_Scene& theScene) { - VrmlData_Scene& aScene = const_cast(theScene); - aScene.myMutex.Lock(); + VrmlData_Scene& aScene = const_cast(theScene); + std::lock_guard aLock(aScene.myMutex); aScene.myCurrentIndent = 0; aScene.myLineError = 0; aScene.myOutput = 0L; @@ -151,7 +150,6 @@ Standard_OStream& operator<<(Standard_OStream& theOutput, const VrmlData_Scene& aScene.myOutput = 0L; aScene.myNamedNodesOut.Clear(); aScene.myUnnamedNodesOut.Clear(); - aScene.myMutex.Unlock(); return theOutput; } @@ -326,8 +324,8 @@ VrmlData_ErrorStatus VrmlData_Scene::readHeader(VrmlData_InBuffer& theBuffer) VrmlData_Scene& VrmlData_Scene::operator<<(Standard_IStream& theInput) { - VrmlData_InBuffer aBuffer(theInput); - myMutex.Lock(); + VrmlData_InBuffer aBuffer(theInput); + std::lock_guard aLock(myMutex); // Read the VRML header myStatus = readHeader(aBuffer); const Handle(VrmlData_UnknownNode) aNullNode = new VrmlData_UnknownNode(*this); @@ -365,7 +363,7 @@ VrmlData_Scene& VrmlData_Scene::operator<<(Standard_IStream& theInput) } if (myStatus != VrmlData_StatusOK) myLineError = aBuffer.LineCount; - myMutex.Unlock(); + return *this; } diff --git a/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Scene.hxx b/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Scene.hxx index 9f08cbb167..c201e90563 100644 --- a/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Scene.hxx +++ b/src/DataExchange/TKDEVRML/VrmlData/VrmlData_Scene.hxx @@ -25,9 +25,10 @@ #include #include #include -#include #include +#include + // resolve name collisions with X11 headers #ifdef Status #undef Status @@ -344,7 +345,7 @@ private: // read from stream NCollection_List myVrmlDir; - Standard_Mutex myMutex; + std::mutex myMutex; Standard_Integer myLineError; ///! #0 if error // write to stream diff --git a/src/DataExchange/TKRWMesh/RWMesh/RWMesh_TriangulationReader.cxx b/src/DataExchange/TKRWMesh/RWMesh/RWMesh_TriangulationReader.cxx index 3762d1d8a0..2a8e7260b8 100644 --- a/src/DataExchange/TKRWMesh/RWMesh/RWMesh_TriangulationReader.cxx +++ b/src/DataExchange/TKRWMesh/RWMesh/RWMesh_TriangulationReader.cxx @@ -132,7 +132,7 @@ bool RWMesh_TriangulationReader::finalizeLoading( } if (myLoadingStatistic) { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); myLoadingStatistic->ExpectedNodesNb += theSourceMesh->NbDeferredNodes(); myLoadingStatistic->ExpectedTrianglesNb += theSourceMesh->NbDeferredTriangles(); myLoadingStatistic->DegeneratedTrianglesNb += theSourceMesh->DegeneratedTriNb(); diff --git a/src/DataExchange/TKRWMesh/RWMesh/RWMesh_TriangulationReader.hxx b/src/DataExchange/TKRWMesh/RWMesh/RWMesh_TriangulationReader.hxx index 39da960951..e911557e6c 100644 --- a/src/DataExchange/TKRWMesh/RWMesh/RWMesh_TriangulationReader.hxx +++ b/src/DataExchange/TKRWMesh/RWMesh/RWMesh_TriangulationReader.hxx @@ -16,7 +16,8 @@ #include #include -#include + +#include class OSD_FileSystem; class RWMesh_TriangulationSource; @@ -306,7 +307,7 @@ protected: RWMesh_CoordinateSystemConverter myCoordSysConverter; //!< coordinate system converter // clang-format off TCollection_AsciiString myFileName; //!< file name to use during message printing - mutable Standard_Mutex myMutex; //!< internal mutex to collect nodes/triangles statistic + mutable std::mutex myMutex; //!< internal mutex to collect nodes/triangles statistic mutable LoadingStatistic* myLoadingStatistic; //!< statistic of loaded triangulation Standard_Boolean myIsDoublePrecision; //!< flag to fill in triangulation using single or double precision Standard_Boolean myToSkipDegenerateTris; //!< flag to skip degenerate triangles during loading, FALSE by default diff --git a/src/DataExchange/TKXSBase/Interface/Interface_Category.cxx b/src/DataExchange/TKXSBase/Interface/Interface_Category.cxx index e41695cd68..27323346b1 100644 --- a/src/DataExchange/TKXSBase/Interface/Interface_Category.cxx +++ b/src/DataExchange/TKXSBase/Interface/Interface_Category.cxx @@ -16,14 +16,14 @@ #include #include #include -#include #include #include +namespace +{ static int THE_Interface_Category_init = 0; static Standard_CString unspec = "unspecified"; -static Standard_Mutex gMapTypesMutex; static volatile Standard_Boolean gMapTypesInit = Standard_False; static NCollection_Vector& theCats() @@ -32,6 +32,14 @@ static NCollection_Vector& theCats() return aCat; } +static std::mutex& GetMapTypesMutex() +{ + static std::mutex gMapTypesMutex; + return gMapTypesMutex; +} + +} // namespace + Standard_Integer Interface_Category::CatNum(const Handle(Standard_Transient)& theEnt, const Interface_ShareTool& theShares) { @@ -118,7 +126,7 @@ void Interface_Category::Init() // On first call, initialize static map if (!gMapTypesInit) { - gMapTypesMutex.Lock(); + std::lock_guard aLock(GetMapTypesMutex()); if (!gMapTypesInit) { if (THE_Interface_Category_init) @@ -139,6 +147,5 @@ void Interface_Category::Init() gMapTypesInit = Standard_True; } - gMapTypesMutex.Unlock(); } } diff --git a/src/DataExchange/TKXSBase/XSAlgo/XSAlgo_AlgoContainer.cxx b/src/DataExchange/TKXSBase/XSAlgo/XSAlgo_AlgoContainer.cxx index 914e52632d..a3963fd4d1 100644 --- a/src/DataExchange/TKXSBase/XSAlgo/XSAlgo_AlgoContainer.cxx +++ b/src/DataExchange/TKXSBase/XSAlgo/XSAlgo_AlgoContainer.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/src/DataExchange/TKXSBase/XSControl/XSControl_TransferWriter.cxx b/src/DataExchange/TKXSBase/XSControl/XSControl_TransferWriter.cxx index 55ab5cd46c..74587e773f 100644 --- a/src/DataExchange/TKXSBase/XSControl/XSControl_TransferWriter.cxx +++ b/src/DataExchange/TKXSBase/XSControl/XSControl_TransferWriter.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/src/DataExchange/TKXSBase/XSControl/XSControl_WorkSession.cxx b/src/DataExchange/TKXSBase/XSControl/XSControl_WorkSession.cxx index 28ca31c754..adf5a5e599 100644 --- a/src/DataExchange/TKXSBase/XSControl/XSControl_WorkSession.cxx +++ b/src/DataExchange/TKXSBase/XSControl/XSControl_WorkSession.cxx @@ -30,12 +30,18 @@ #include #include +#include + IMPLEMENT_STANDARD_RTTIEXT(XSControl_WorkSession, IFSelect_WorkSession) namespace { -static Standard_Mutex WS_GLOBAL_MUTEX; //!< Mutex to prevent data races during reading and writing. +std::mutex& GetGlobalMutex() +{ + static std::mutex WS_GLOBAL_MUTEX; + return WS_GLOBAL_MUTEX; } +} // namespace //================================================================================================= @@ -72,7 +78,7 @@ void XSControl_WorkSession::ClearData(const Standard_Integer mode) Standard_Boolean XSControl_WorkSession::SelectNorm(const Standard_CString normname) { - const Standard_Mutex::Sentry aMutexLock(WS_GLOBAL_MUTEX); + const std::lock_guard aLock(GetGlobalMutex()); // Old norm and results myTransferReader->Clear(-1); // ???? Strictly speaking, cleanup to do in XWS: remove the items @@ -430,8 +436,8 @@ Standard_Integer XSControl_WorkSession::TransferReadRoots(const Message_Progress Handle(Interface_InterfaceModel) XSControl_WorkSession::NewModel() { - const Standard_Mutex::Sentry aMutexLock(WS_GLOBAL_MUTEX); - Handle(Interface_InterfaceModel) newmod; + const std::lock_guard aLock(GetGlobalMutex()); + Handle(Interface_InterfaceModel) newmod; if (myController.IsNull()) return newmod; newmod = myController->NewModel(); @@ -453,8 +459,8 @@ IFSelect_ReturnStatus XSControl_WorkSession::TransferWriteShape( const Standard_Boolean compgraph, const Message_ProgressRange& theProgress) { - const Standard_Mutex::Sentry aMutexLock(WS_GLOBAL_MUTEX); - IFSelect_ReturnStatus status; + const std::lock_guard aLock(GetGlobalMutex()); + IFSelect_ReturnStatus status; if (myController.IsNull()) return IFSelect_RetError; const Handle(Interface_InterfaceModel)& model = Model(); diff --git a/src/Draw/TKDCAF/DNaming/DNaming_ModelingCommands.cxx b/src/Draw/TKDCAF/DNaming/DNaming_ModelingCommands.cxx index 2c09683621..88a38a6e55 100644 --- a/src/Draw/TKDCAF/DNaming/DNaming_ModelingCommands.cxx +++ b/src/Draw/TKDCAF/DNaming/DNaming_ModelingCommands.cxx @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Draw/TKDraw/Draw/Draw_ProgressIndicator.hxx b/src/Draw/TKDraw/Draw/Draw_ProgressIndicator.hxx index 88e4e9d63b..af634023e3 100644 --- a/src/Draw/TKDraw/Draw/Draw_ProgressIndicator.hxx +++ b/src/Draw/TKDraw/Draw/Draw_ProgressIndicator.hxx @@ -19,6 +19,7 @@ #include #include +#include #include class Draw_ProgressIndicator; diff --git a/src/Draw/TKQADraw/QABugs/QABugs_20.cxx b/src/Draw/TKQADraw/QABugs/QABugs_20.cxx index 176a4ad18c..15098f9e8f 100644 --- a/src/Draw/TKQADraw/QABugs/QABugs_20.cxx +++ b/src/Draw/TKQADraw/QABugs/QABugs_20.cxx @@ -3707,7 +3707,6 @@ static Standard_Integer OCC29745(Draw_Interpretor& theDI, return 0; } -#include #include #include #include diff --git a/src/Draw/TKViewerTest/ViewerTest/ViewerTest_ContinuousRedrawer.cxx b/src/Draw/TKViewerTest/ViewerTest/ViewerTest_ContinuousRedrawer.cxx index f4f05288c8..a783705778 100644 --- a/src/Draw/TKViewerTest/ViewerTest/ViewerTest_ContinuousRedrawer.cxx +++ b/src/Draw/TKViewerTest/ViewerTest/ViewerTest_ContinuousRedrawer.cxx @@ -66,7 +66,7 @@ void ViewerTest_ContinuousRedrawer::Start(const Handle(V3d_View)& theView, else { { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); myToStop = false; myToPause = false; } @@ -84,7 +84,7 @@ void ViewerTest_ContinuousRedrawer::Stop(const Handle(V3d_View)& theView) } { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); myToStop = true; myToPause = false; } @@ -100,7 +100,7 @@ void ViewerTest_ContinuousRedrawer::Pause() { if (!myToPause) { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); myToPause = true; } } @@ -118,7 +118,7 @@ void ViewerTest_ContinuousRedrawer::doThreadLoop() { bool toPause = false; { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); if (myToStop) { return; diff --git a/src/Draw/TKViewerTest/ViewerTest/ViewerTest_ContinuousRedrawer.hxx b/src/Draw/TKViewerTest/ViewerTest/ViewerTest_ContinuousRedrawer.hxx index cf2c259243..8987cf78e0 100644 --- a/src/Draw/TKViewerTest/ViewerTest/ViewerTest_ContinuousRedrawer.hxx +++ b/src/Draw/TKViewerTest/ViewerTest/ViewerTest_ContinuousRedrawer.hxx @@ -16,9 +16,10 @@ #include #include -#include #include +#include + class V3d_View; //! Auxiliary tool performing continuous redraws of specified window. @@ -70,7 +71,7 @@ private: private: Handle(V3d_View) myView; //!< view to invalidate OSD_Thread myThread; //!< working thread - Standard_Mutex myMutex; //!< mutex for accessing common variables + std::mutex myMutex; //!< mutex for accessing common variables Standard_Condition myWakeEvent; //!< event to wake up working thread Standard_Real myTargetFps; //!< desired update framerate volatile bool myToStop; //!< flag to stop working thread diff --git a/src/Draw/TKXSDRAWIGES/XSDRAWIGES/XSDRAWIGES.cxx b/src/Draw/TKXSDRAWIGES/XSDRAWIGES/XSDRAWIGES.cxx index 0c4d5e2dfd..4623a202d2 100644 --- a/src/Draw/TKXSDRAWIGES/XSDRAWIGES/XSDRAWIGES.cxx +++ b/src/Draw/TKXSDRAWIGES/XSDRAWIGES/XSDRAWIGES.cxx @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Draw/TKXSDRAWSTL/XSDRAWSTL/XSDRAWSTL.cxx b/src/Draw/TKXSDRAWSTL/XSDRAWSTL/XSDRAWSTL.cxx index b2065b7627..ddc436c2e2 100644 --- a/src/Draw/TKXSDRAWSTL/XSDRAWSTL/XSDRAWSTL.cxx +++ b/src/Draw/TKXSDRAWSTL/XSDRAWSTL/XSDRAWSTL.cxx @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/src/FoundationClasses/TKMath/BVH/BVH_BuildQueue.cxx b/src/FoundationClasses/TKMath/BVH/BVH_BuildQueue.cxx index 2c8a909178..c9850242b1 100644 --- a/src/FoundationClasses/TKMath/BVH/BVH_BuildQueue.cxx +++ b/src/FoundationClasses/TKMath/BVH/BVH_BuildQueue.cxx @@ -21,15 +21,8 @@ // ======================================================================= Standard_Integer BVH_BuildQueue::Size() { - Standard_Integer aSize; - - myMutex.Lock(); - { - aSize = myQueue.Size(); - } - myMutex.Unlock(); - - return aSize; + std::lock_guard aLock(myMutex); + return myQueue.Size(); } // ======================================================================= @@ -38,11 +31,8 @@ Standard_Integer BVH_BuildQueue::Size() // ======================================================================= void BVH_BuildQueue::Enqueue(const Standard_Integer& theWorkItem) { - myMutex.Lock(); - { - myQueue.Append(theWorkItem); - } - myMutex.Unlock(); + std::lock_guard aLock(myMutex); + myQueue.Append(theWorkItem); } // ======================================================================= @@ -51,31 +41,29 @@ void BVH_BuildQueue::Enqueue(const Standard_Integer& theWorkItem) // ======================================================================= Standard_Integer BVH_BuildQueue::Fetch(Standard_Boolean& wasBusy) { + std::lock_guard aLock(myMutex); + Standard_Integer aQuery = -1; + if (!myQueue.IsEmpty()) { - Standard_Mutex::Sentry aSentry(myMutex); - - if (!myQueue.IsEmpty()) - { - aQuery = myQueue.First(); + aQuery = myQueue.First(); - myQueue.Remove(1); // remove item from queue - } + myQueue.Remove(1); // remove item from queue + } - if (aQuery != -1) - { - if (!wasBusy) - { - ++myNbThreads; - } - } - else if (wasBusy) + if (aQuery != -1) + { + if (!wasBusy) { - --myNbThreads; + ++myNbThreads; } - - wasBusy = aQuery != -1; } + else if (wasBusy) + { + --myNbThreads; + } + + wasBusy = aQuery != -1; return aQuery; } diff --git a/src/FoundationClasses/TKMath/BVH/BVH_BuildQueue.hxx b/src/FoundationClasses/TKMath/BVH/BVH_BuildQueue.hxx index bc44b62958..b83762030b 100644 --- a/src/FoundationClasses/TKMath/BVH/BVH_BuildQueue.hxx +++ b/src/FoundationClasses/TKMath/BVH/BVH_BuildQueue.hxx @@ -18,9 +18,10 @@ #include -#include #include +#include + //! Command-queue for parallel building of BVH nodes. class BVH_BuildQueue { @@ -60,7 +61,7 @@ protected: protected: //! Manages access serialization of working threads. - Standard_Mutex myMutex; + std::mutex myMutex; //! Number of active build threads. Standard_Integer myNbThreads; diff --git a/src/FoundationClasses/TKMath/BVH/BVH_QueueBuilder.hxx b/src/FoundationClasses/TKMath/BVH/BVH_QueueBuilder.hxx index 917cccd379..dbd3cea4df 100644 --- a/src/FoundationClasses/TKMath/BVH/BVH_QueueBuilder.hxx +++ b/src/FoundationClasses/TKMath/BVH/BVH_QueueBuilder.hxx @@ -20,6 +20,8 @@ #include #include +#include + //! Abstract BVH builder based on the concept of work queue. //! Queue based BVH builders support parallelization with a //! fixed number of threads (maximum efficiency is achieved @@ -177,7 +179,7 @@ void BVH_QueueBuilder::addChildren( // Add child nodes { - Standard_Mutex::Sentry aSentry(theBuildQueue.myMutex); + std::lock_guard aLock(theBuildQueue.myMutex); for (Standard_Integer anIdx = 0; anIdx < 2; ++anIdx) { diff --git a/src/FoundationClasses/TKernel/Message/Message_MsgFile.cxx b/src/FoundationClasses/TKernel/Message/Message_MsgFile.cxx index 7d81bd895e..dc7f3f7dba 100644 --- a/src/FoundationClasses/TKernel/Message/Message_MsgFile.cxx +++ b/src/FoundationClasses/TKernel/Message/Message_MsgFile.cxx @@ -19,11 +19,11 @@ #include #include #include -#include #include #include #include +#include typedef NCollection_DataMap Message_DataMapOfExtendedString; @@ -35,9 +35,9 @@ static Message_DataMapOfExtendedString& msgsDataMap() } // mutex used to prevent concurrent access to message registry -static Standard_Mutex& Message_MsgFile_Mutex() +static std::mutex& Message_MsgFile_Mutex() { - static Standard_Mutex theMutex; + static std::mutex theMutex; return theMutex; } @@ -371,7 +371,7 @@ Standard_Boolean Message_MsgFile::AddMsg(const TCollection_AsciiString& theKe { Message_DataMapOfExtendedString& aDataMap = ::msgsDataMap(); - Standard_Mutex::Sentry aSentry(Message_MsgFile_Mutex()); + std::lock_guard aLock(Message_MsgFile_Mutex()); aDataMap.Bind(theKeyword, theMessage); return Standard_True; } @@ -390,7 +390,7 @@ const TCollection_ExtendedString& Message_MsgFile::Msg(const Standard_CString th Standard_Boolean Message_MsgFile::HasMsg(const TCollection_AsciiString& theKeyword) { - Standard_Mutex::Sentry aSentry(Message_MsgFile_Mutex()); + std::lock_guard aLock(Message_MsgFile_Mutex()); return ::msgsDataMap().IsBound(theKeyword); } @@ -402,7 +402,7 @@ const TCollection_ExtendedString& Message_MsgFile::Msg(const TCollection_AsciiSt { // find message in the map Message_DataMapOfExtendedString& aDataMap = ::msgsDataMap(); - Standard_Mutex::Sentry aSentry(Message_MsgFile_Mutex()); + std::lock_guard aLock(Message_MsgFile_Mutex()); // if message is not found, generate error message and add it to the map to minimize overhead // on consequent calls with the same key diff --git a/src/FoundationClasses/TKernel/Message/Message_ProgressIndicator.hxx b/src/FoundationClasses/TKernel/Message/Message_ProgressIndicator.hxx index 4e7b55ebe8..1a5a7c42c8 100644 --- a/src/FoundationClasses/TKernel/Message/Message_ProgressIndicator.hxx +++ b/src/FoundationClasses/TKernel/Message/Message_ProgressIndicator.hxx @@ -16,8 +16,11 @@ #ifndef _Message_ProgressIndicator_HeaderFile #define _Message_ProgressIndicator_HeaderFile -#include #include +#include +#include + +#include DEFINE_STANDARD_HANDLE(Message_ProgressIndicator, Standard_Transient) @@ -135,7 +138,7 @@ private: private: Standard_Real myPosition; //!< Total progress position ranged from 0 to 1 - Standard_Mutex myMutex; //!< Protection of myPosition from concurrent increment + std::mutex myMutex; //!< Protection of myPosition from concurrent increment Message_ProgressScope* myRootScope; //!< The root progress scope private: @@ -151,7 +154,7 @@ inline void Message_ProgressIndicator::Increment(const Standard_Real th const Message_ProgressScope& theScope) { // protect incrementation by mutex to avoid problems in multithreaded scenarios - Standard_Mutex::Sentry aSentry(myMutex); + std::lock_guard aLock(myMutex); myPosition = Min(myPosition + theStep, 1.); diff --git a/src/FoundationClasses/TKernel/Message/Message_Report.cxx b/src/FoundationClasses/TKernel/Message/Message_Report.cxx index fc09ed5514..c8071fdc8c 100644 --- a/src/FoundationClasses/TKernel/Message/Message_Report.cxx +++ b/src/FoundationClasses/TKernel/Message/Message_Report.cxx @@ -41,7 +41,7 @@ Message_Report::Message_Report() void Message_Report::AddAlert(Message_Gravity theGravity, const Handle(Message_Alert)& theAlert) { - Standard_Mutex::Sentry aSentry(myMutex); + std::lock_guard aLock(myMutex); // alerts of the top level if (myAlertLevels.IsEmpty()) @@ -168,7 +168,7 @@ void Message_Report::UpdateActiveInMessenger(const Handle(Message_Messenger)& th void Message_Report::AddLevel(Message_Level* theLevel, const TCollection_AsciiString& theName) { - Standard_Mutex::Sentry aSentry(myMutex); + std::lock_guard aLock(myMutex); myAlertLevels.Append(theLevel); @@ -204,7 +204,7 @@ void Message_Report::AddLevel(Message_Level* theLevel, const TCollection_AsciiSt void Message_Report::RemoveLevel(Message_Level* theLevel) { - Standard_Mutex::Sentry aSentry(myMutex); + std::lock_guard aLock(myMutex); for (int aLevelIndex = myAlertLevels.Size(); aLevelIndex >= 1; aLevelIndex--) { @@ -228,7 +228,7 @@ void Message_Report::Clear() return; } - Standard_Mutex::Sentry aSentry(myMutex); + std::lock_guard aLock(myMutex); compositeAlerts()->Clear(); myAlertLevels.Clear(); @@ -243,7 +243,7 @@ void Message_Report::Clear(Message_Gravity theGravity) return; } - Standard_Mutex::Sentry aSentry(myMutex); + std::lock_guard aLock(myMutex); compositeAlerts()->Clear(theGravity); myAlertLevels.Clear(); @@ -258,7 +258,7 @@ void Message_Report::Clear(const Handle(Standard_Type)& theType) return; } - Standard_Mutex::Sentry aSentry(myMutex); + std::lock_guard aLock(myMutex); compositeAlerts()->Clear(theType); myAlertLevels.Clear(); diff --git a/src/FoundationClasses/TKernel/Message/Message_Report.hxx b/src/FoundationClasses/TKernel/Message/Message_Report.hxx index 983414a270..88019f312d 100644 --- a/src/FoundationClasses/TKernel/Message/Message_Report.hxx +++ b/src/FoundationClasses/TKernel/Message/Message_Report.hxx @@ -21,7 +21,8 @@ #include #include #include -#include + +#include class Message_CompositeAlerts; class Message_Messenger; @@ -175,7 +176,7 @@ protected: const Handle(Message_CompositeAlerts)& theCompositeAlert); protected: - Standard_Mutex myMutex; + std::mutex myMutex; Handle(Message_CompositeAlerts) myCompositAlerts; //!< container of alerts diff --git a/src/FoundationClasses/TKernel/NCollection/NCollection_HeapAllocator.cxx b/src/FoundationClasses/TKernel/NCollection/NCollection_HeapAllocator.cxx index f89a815404..c77ffb4883 100644 --- a/src/FoundationClasses/TKernel/NCollection/NCollection_HeapAllocator.cxx +++ b/src/FoundationClasses/TKernel/NCollection/NCollection_HeapAllocator.cxx @@ -15,7 +15,6 @@ #include #include -#include IMPLEMENT_STANDARD_RTTIEXT(NCollection_HeapAllocator, NCollection_BaseAllocator) @@ -47,15 +46,6 @@ void NCollection_HeapAllocator::Free(void* anAddress) const Handle(NCollection_HeapAllocator)& NCollection_HeapAllocator::GlobalHeapAllocator() { - static Handle(NCollection_HeapAllocator) pAllocator; - if (pAllocator.IsNull()) - { - static Standard_Mutex theMutex; - Standard_Mutex::Sentry aSentry(theMutex); - if (pAllocator.IsNull()) - { - pAllocator = new NCollection_HeapAllocator; - } - } + static Handle(NCollection_HeapAllocator) pAllocator = new NCollection_HeapAllocator; return pAllocator; } diff --git a/src/FoundationClasses/TKernel/NCollection/NCollection_IncAllocator.cxx b/src/FoundationClasses/TKernel/NCollection/NCollection_IncAllocator.cxx index 1e4dc38950..a43bda2931 100644 --- a/src/FoundationClasses/TKernel/NCollection/NCollection_IncAllocator.cxx +++ b/src/FoundationClasses/TKernel/NCollection/NCollection_IncAllocator.cxx @@ -13,7 +13,6 @@ #include -#include #include #include @@ -72,13 +71,12 @@ void NCollection_IncAllocator::SetThreadSafe(const bool theIsThreadSafe) { if (!myMutex) { - myMutex = new Standard_Mutex; + myMutex = opencascade::make_unique(); } } else { - delete myMutex; - myMutex = nullptr; + myMutex.reset(); } } @@ -87,14 +85,14 @@ void NCollection_IncAllocator::SetThreadSafe(const bool theIsThreadSafe) NCollection_IncAllocator::~NCollection_IncAllocator() { clean(); - delete myMutex; } //================================================================================================= void* NCollection_IncAllocator::AllocateOptimal(const size_t theSize) { - Standard_Mutex::Sentry aLock(myMutex); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); // Allocating using general block IBlock* aBlock = nullptr; // Use allocated blocks @@ -164,8 +162,9 @@ void* NCollection_IncAllocator::Allocate(const size_t theSize) void NCollection_IncAllocator::clean() { - Standard_Mutex::Sentry aLock(myMutex); - IBlock* aHeapIter = myOrderedBlocks; + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); + IBlock* aHeapIter = myOrderedBlocks; while (aHeapIter) { IBlock* aCur = aHeapIter; @@ -221,8 +220,9 @@ void NCollection_IncAllocator::Reset(const Standard_Boolean theReleaseMemory) clean(); return; } - Standard_Mutex::Sentry aLock(myMutex); - IBlock* aHeapIter = myOrderedBlocks; + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); + IBlock* aHeapIter = myOrderedBlocks; while (aHeapIter) { IBlock* aCur = aHeapIter; diff --git a/src/FoundationClasses/TKernel/NCollection/NCollection_IncAllocator.hxx b/src/FoundationClasses/TKernel/NCollection/NCollection_IncAllocator.hxx index 185f9da82f..a3da51b966 100644 --- a/src/FoundationClasses/TKernel/NCollection/NCollection_IncAllocator.hxx +++ b/src/FoundationClasses/TKernel/NCollection/NCollection_IncAllocator.hxx @@ -17,10 +17,10 @@ #include #include #include +#include #include - -class Standard_Mutex; +#include /** * Class NCollection_IncAllocator - incremental memory allocator. This class @@ -132,12 +132,12 @@ public: static constexpr size_t THE_MINIMUM_BLOCK_SIZE = 1024 * 2; private: - unsigned int myBlockSize; //!< Block size to incremental allocations - unsigned int myBlockCount = 0; //!< Count of created blocks - Standard_Mutex* myMutex = nullptr; //!< Thread-safety mutex - IBlock* myAllocationHeap = nullptr; //!< Sorted list for allocations - IBlock* myUsedHeap = nullptr; //!< Sorted list for store empty blocks - IBlock* myOrderedBlocks = nullptr; //!< Ordered list for store growing size blocks + unsigned int myBlockSize; //!< Block size to incremental allocations + unsigned int myBlockCount = 0; //!< Count of created blocks + std::unique_ptr myMutex = nullptr; //!< Thread-safety mutex + IBlock* myAllocationHeap = nullptr; //!< Sorted list for allocations + IBlock* myUsedHeap = nullptr; //!< Sorted list for store empty blocks + IBlock* myOrderedBlocks = nullptr; //!< Ordered list for store growing size blocks public: // Declaration of CASCADE RTTI diff --git a/src/FoundationClasses/TKernel/OSD/OSD_Environment.cxx b/src/FoundationClasses/TKernel/OSD/OSD_Environment.cxx index 629f2d2f85..2f2bab6244 100644 --- a/src/FoundationClasses/TKernel/OSD/OSD_Environment.cxx +++ b/src/FoundationClasses/TKernel/OSD/OSD_Environment.cxx @@ -12,22 +12,24 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + #ifndef _WIN32 - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include - #include - #include - #include static const OSD_WhoAmI Iam = OSD_WEnvironment; // ---------------------------------------------------------------------- @@ -120,8 +122,8 @@ void OSD_Environment::Build() static int Ibuffer = 0; // Tout ca pour putenv,getenv // Use mutex to avoid concurrent access to the buffer - static Standard_Mutex theMutex; - Standard_Mutex::Sentry aSentry(theMutex); + static std::mutex aMutex; + std::lock_guard aLock(aMutex); // check if such variable has already been created in the buffer int index = -1, len = myName.Length(); @@ -216,17 +218,13 @@ Standard_Integer OSD_Environment::Error() const #include - #include - #include - #include - #include #ifdef OCCT_UWP namespace { // emulate global map of environment variables -static Standard_Mutex THE_ENV_LOCK; +static std::mutex THE_ENV_LOCK; static NCollection_DataMap THE_ENV_MAP; } // namespace #else @@ -262,7 +260,7 @@ TCollection_AsciiString OSD_Environment::Value() { myValue.Clear(); #ifdef OCCT_UWP - Standard_Mutex::Sentry aLock(THE_ENV_LOCK); + std::lock_guard aLock(THE_ENV_LOCK); THE_ENV_MAP.Find(myName, myValue); #else @@ -318,7 +316,7 @@ TCollection_AsciiString OSD_Environment ::Name() const void OSD_Environment::Build() { #ifdef OCCT_UWP - Standard_Mutex::Sentry aLock(THE_ENV_LOCK); + std::lock_guard aLock(THE_ENV_LOCK); THE_ENV_MAP.Bind(myName, myValue); #else NCollection_Utf8String aSetVariable = @@ -330,7 +328,7 @@ void OSD_Environment::Build() void OSD_Environment::Remove() { #ifdef OCCT_UWP - Standard_Mutex::Sentry aLock(THE_ENV_LOCK); + std::lock_guard aLock(THE_ENV_LOCK); THE_ENV_MAP.UnBind(myName); #else NCollection_Utf8String aSetVariable = NCollection_Utf8String(myName.ToCString()) + "="; diff --git a/src/FoundationClasses/TKernel/OSD/OSD_Parallel_Threads.cxx b/src/FoundationClasses/TKernel/OSD/OSD_Parallel_Threads.cxx index 2d10d4bd31..5fff7d7ce2 100644 --- a/src/FoundationClasses/TKernel/OSD/OSD_Parallel_Threads.cxx +++ b/src/FoundationClasses/TKernel/OSD/OSD_Parallel_Threads.cxx @@ -19,9 +19,10 @@ #include #include -#include #include +#include + namespace { //! Class implementing tools for parallel processing @@ -55,7 +56,7 @@ public: //! Thread-safe method. inline OSD_Parallel::UniversalIterator It() const { - Standard_Mutex::Sentry aMutex(myMutex); + std::lock_guard aMutex(myMutex); return (myIt != myEnd) ? myIt++ : myEnd; } @@ -71,7 +72,7 @@ public: const OSD_Parallel::UniversalIterator& myEnd; //!< Last element of range. // clang-format off mutable OSD_Parallel::UniversalIterator myIt; //!< First non processed element of range. - mutable Standard_Mutex myMutex; //!< Access controller for the first non processed element. + mutable std::mutex myMutex; //!< Access controller for the first non processed element. // clang-format on }; diff --git a/src/FoundationClasses/TKernel/OSD/OSD_ThreadPool.cxx b/src/FoundationClasses/TKernel/OSD/OSD_ThreadPool.cxx index 140b3197b4..f0de6d0b6f 100644 --- a/src/FoundationClasses/TKernel/OSD/OSD_ThreadPool.cxx +++ b/src/FoundationClasses/TKernel/OSD/OSD_ThreadPool.cxx @@ -16,6 +16,7 @@ #include #include +#include #include IMPLEMENT_STANDARD_RTTIEXT(OSD_ThreadPool, Standard_Transient) diff --git a/src/FoundationClasses/TKernel/OSD/OSD_ThreadPool.hxx b/src/FoundationClasses/TKernel/OSD/OSD_ThreadPool.hxx index d551138c70..949fa4668f 100644 --- a/src/FoundationClasses/TKernel/OSD/OSD_ThreadPool.hxx +++ b/src/FoundationClasses/TKernel/OSD/OSD_ThreadPool.hxx @@ -18,7 +18,6 @@ #include #include #include -#include #include diff --git a/src/FoundationClasses/TKernel/OSD/OSD_signal.cxx b/src/FoundationClasses/TKernel/OSD/OSD_signal.cxx index 642fd1e1d6..85c4920d74 100644 --- a/src/FoundationClasses/TKernel/OSD/OSD_signal.cxx +++ b/src/FoundationClasses/TKernel/OSD/OSD_signal.cxx @@ -17,6 +17,9 @@ #include #include +#include +#include + #include static OSD_SignalMode OSD_WasSetSignal = OSD_SignalMode_AsIs; @@ -76,7 +79,6 @@ void OSD::SetSignalStackTraceLength(Standard_Integer theLength) #include #include #include - #include #ifdef _MSC_VER #include @@ -84,7 +86,6 @@ void OSD::SetSignalStackTraceLength(Standard_Integer theLength) #endif #include - #include #include static Standard_Boolean fCtrlBrk; @@ -92,7 +93,7 @@ static Standard_Boolean fCtrlBrk; static Standard_Boolean fMsgBox; // used to forbid simultaneous execution of setting / executing handlers -static Standard_Mutex THE_SIGNAL_MUTEX; +static std::mutex THE_SIGNAL_MUTEX; static LONG __fastcall _osd_raise(DWORD theCode, const char* theMsg, const char* theStack); static BOOL WINAPI _osd_ctrl_break_handler(DWORD); @@ -121,9 +122,9 @@ static LONG CallHandler(DWORD theExceptionCode, EXCEPTION_POINTERS* theExcPtr) ExceptionInformation0 = theExcPtr->ExceptionRecord->ExceptionInformation[0]; } - // clang-format off - Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling - // clang-format on + // lock the mutex to prevent simultaneous handling + std::lock_guard aLock(THE_SIGNAL_MUTEX); + static char aBuffer[2048]; bool isFloatErr = false; @@ -309,9 +310,9 @@ static LONG CallHandler(DWORD theExceptionCode, EXCEPTION_POINTERS* theExcPtr) //======================================================================= static void SIGWntHandler(int signum, int sub_code) { - // clang-format off - Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling - // clang-format on + // lock the mutex to prevent simultaneous handling + std::lock_guard aLock(THE_SIGNAL_MUTEX); + switch (signum) { case SIGFPE: @@ -379,9 +380,6 @@ static void SIGWntHandler(int signum, int sub_code) static void TranslateSE(unsigned int theCode, EXCEPTION_POINTERS* theExcPtr) { - // clang-format off - Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling - // clang-format on CallHandler(theCode, theExcPtr); } #endif @@ -440,9 +438,9 @@ void OSD::SetThreadLocalSignal(OSD_SignalMode theSignalMode, Standard_Boolean th void OSD::SetSignal(OSD_SignalMode theSignalMode, Standard_Boolean theFloatingSignal) { - // clang-format off - Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling - // clang-format on + // lock the mutex to prevent simultaneous handling + std::lock_guard aLock(THE_SIGNAL_MUTEX); + OSD_WasSetSignal = theSignalMode; #if !defined(OCCT_UWP) || defined(NTDDI_WIN10_TH2) @@ -759,7 +757,6 @@ ACT_SIGIO_HANDLER* ADR_ACT_SIGIO_HANDLER = NULL; #ifdef __GNUC__ #include - #include #else #ifdef SA_SIGINFO #include @@ -767,8 +764,6 @@ ACT_SIGIO_HANDLER* ADR_ACT_SIGIO_HANDLER = NULL; #endif typedef void (*SIG_PFV)(int); - #include - #if !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__) && defined(__GLIBC__) #include #endif diff --git a/src/FoundationClasses/TKernel/Standard/Standard_ErrorHandler.cxx b/src/FoundationClasses/TKernel/Standard/Standard_ErrorHandler.cxx index 5ec6e4865a..c5c8beed0c 100644 --- a/src/FoundationClasses/TKernel/Standard/Standard_ErrorHandler.cxx +++ b/src/FoundationClasses/TKernel/Standard/Standard_ErrorHandler.cxx @@ -18,9 +18,11 @@ //============================================================================ #include #include -#include #include +#include +#include + #ifndef _WIN32 #include #else @@ -39,16 +41,19 @@ //==== The top of the Errors Stack =========================================== static Standard_ErrorHandler* Top = 0; -//! 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() +//================================================================================================= + +namespace { - static Standard_Mutex theMutex; - return theMutex; -} +// Using std::shared_mutex to allow concurrent read access from multiple threads. +// Most FindHandler calls (theUnlink=false) use shared_lock for concurrent searches. +// Only write operations (constructor, Unlink, FindHandler with theUnlink=true) use unique_lock. +// +// TODO: Long-term optimization - use thread_local storage to eliminate locking entirely. +// Since each thread only accesses its own error handlers (filtered by thread ID), +// this global list could be replaced with thread_local Top pointers. +// This would eliminate all mutex overhead for thousands of try blocks in multi-threaded code. +static std::shared_mutex THE_GLOBAL_MUTEX; static inline Standard_ThreadId GetThreadID() { @@ -58,6 +63,7 @@ static inline Standard_ThreadId GetThreadID() return GetCurrentThreadId(); #endif } +} // namespace //============================================================================ //==== Constructor : Create a ErrorHandler structure. And add it at the @@ -71,10 +77,9 @@ Standard_ErrorHandler::Standard_ErrorHandler() myThread = GetThreadID(); memset(&myLabel, 0, sizeof(myLabel)); - GetMutex().Lock(); + std::unique_lock aLock(THE_GLOBAL_MUTEX); myPrevious = Top; Top = this; - GetMutex().Unlock(); } //============================================================================ @@ -96,7 +101,7 @@ void Standard_ErrorHandler::Destroy() void Standard_ErrorHandler::Unlink() { // put a lock on the stack - GetMutex().Lock(); + std::unique_lock aLock(THE_GLOBAL_MUTEX); Standard_ErrorHandler* aPrevious = 0; Standard_ErrorHandler* aCurrent = Top; @@ -110,7 +115,6 @@ void Standard_ErrorHandler::Unlink() if (aCurrent == 0) { - GetMutex().Unlock(); return; } @@ -124,7 +128,6 @@ void Standard_ErrorHandler::Unlink() aPrevious->myPrevious = aCurrent->myPrevious; } myPrevious = 0; - GetMutex().Unlock(); // unlink and destroy all registered callbacks Standard_Address aPtr = aCurrent->myCallbackPtr; @@ -223,32 +226,54 @@ void Standard_ErrorHandler::Error(const Handle(Standard_Failure)& theError) Standard_ErrorHandler* Standard_ErrorHandler::FindHandler(const Standard_HandlerStatus theStatus, const Standard_Boolean theUnlink) { - // lock the stack - GetMutex().Lock(); + // Use shared lock for read-only access (most common case), exclusive lock only when modifying + if (!theUnlink) + { + // Read-only path - use shared lock to allow concurrent searches from multiple threads + std::shared_lock aLock(THE_GLOBAL_MUTEX); - // Find the current ErrorHandler according to thread - Standard_ErrorHandler* aPrevious = 0; - Standard_ErrorHandler* aCurrent = Top; - Standard_ErrorHandler* anActive = 0; - Standard_Boolean aStop = Standard_False; - Standard_ThreadId aTreadId = GetThreadID(); + // Find the current ErrorHandler according to thread + Standard_ErrorHandler* aCurrent = Top; + Standard_ThreadId aTreadId = GetThreadID(); - // searching an exception with correct ID number - // which is not processed for the moment - while (!aStop) - { - while (aCurrent != NULL && aTreadId != aCurrent->myThread) + // searching an exception with correct ID number + while (aCurrent != NULL) { - aPrevious = aCurrent; - aCurrent = aCurrent->myPrevious; + if (aTreadId == aCurrent->myThread && theStatus == aCurrent->myStatus) + { + // found one + return aCurrent; + } + aCurrent = aCurrent->myPrevious; } - if (aCurrent != NULL) + return NULL; + } + else + { + // Modifying path - use exclusive lock + std::unique_lock aLock(THE_GLOBAL_MUTEX); + + // Find the current ErrorHandler according to thread + Standard_ErrorHandler* aPrevious = 0; + Standard_ErrorHandler* aCurrent = Top; + Standard_ErrorHandler* anActive = 0; + Standard_Boolean aStop = Standard_False; + Standard_ThreadId aTreadId = GetThreadID(); + + // searching an exception with correct ID number + // which is not processed for the moment + while (!aStop) { - if (theStatus != aCurrent->myStatus) + while (aCurrent != NULL && aTreadId != aCurrent->myThread) { + aPrevious = aCurrent; + aCurrent = aCurrent->myPrevious; + } - if (theUnlink) + if (aCurrent != NULL) + { + if (theStatus != aCurrent->myStatus) { // unlink current if (aPrevious == 0) @@ -260,27 +285,26 @@ Standard_ErrorHandler* Standard_ErrorHandler::FindHandler(const Standard_Handler { aPrevious->myPrevious = aCurrent->myPrevious; } - } - // shift - aCurrent = aCurrent->myPrevious; + // shift + aCurrent = aCurrent->myPrevious; + } + else + { + // found one + anActive = aCurrent; + aStop = Standard_True; + } } else { - // found one - anActive = aCurrent; - aStop = Standard_True; + // Current is NULL, means that no handles + aStop = Standard_True; } } - else - { - // Current is NULL, means that no handlesr - aStop = Standard_True; - } - } - GetMutex().Unlock(); - return anActive; + return anActive; + } } #if defined(OCC_CONVERT_SIGNALS) diff --git a/src/FoundationClasses/TKernel/Standard/Standard_ErrorHandler.hxx b/src/FoundationClasses/TKernel/Standard/Standard_ErrorHandler.hxx index 1eec747533..f43109bf64 100644 --- a/src/FoundationClasses/TKernel/Standard/Standard_ErrorHandler.hxx +++ b/src/FoundationClasses/TKernel/Standard/Standard_ErrorHandler.hxx @@ -26,6 +26,8 @@ #include #include +#include + //! @file //! Support of handling of C signals as C++-style exceptions, and implementation //! of C++ exception handling on platforms that do not implement these natively. diff --git a/src/FoundationClasses/TKernel/Standard/Standard_MMgrOpt.cxx b/src/FoundationClasses/TKernel/Standard/Standard_MMgrOpt.cxx index 1ed2bf5e48..5ba1e5176b 100644 --- a/src/FoundationClasses/TKernel/Standard/Standard_MMgrOpt.cxx +++ b/src/FoundationClasses/TKernel/Standard/Standard_MMgrOpt.cxx @@ -25,6 +25,7 @@ #include #ifndef _WIN32 + #include #include /* mmap() */ #endif @@ -310,9 +311,7 @@ Standard_Address Standard_MMgrOpt::Allocate(const Standard_Size aSize) // object life (such as myThreshold), and assume that calls to functions // of standard library are already protected by their implementation. // The unlock is called as soon as possible, for every treatment case. - // We also do not use Sentry, since in case if OCC signal or exception is - // caused by this block we will have deadlock anyway... - myMutex.Lock(); + myMutex.lock(); // if free block of the requested size is available, return it if (myFreeList[Index]) @@ -324,7 +323,7 @@ Standard_Address Standard_MMgrOpt::Allocate(const Standard_Size aSize) myFreeList[Index] = *(Standard_Size**)aBlock; // unlock the mutex - myMutex.Unlock(); + myMutex.unlock(); // record size of the allocated block in the block header and // shift the pointer to the beginning of the user part of block @@ -339,12 +338,12 @@ Standard_Address Standard_MMgrOpt::Allocate(const Standard_Size aSize) else if (RoundSize <= myCellSize) { // unlock the mutex for free lists - myMutex.Unlock(); + myMutex.unlock(); // and lock the specific mutex used to protect access to small blocks pools; // note that this is done by sentry class so as to ensure unlocking in case of // possible exception that may be thrown from AllocMemory() - Standard_Mutex::Sentry aSentry(myMutexPools); + std::lock_guard aLock(myMutexPools); // check for availability of requested space in the current pool Standard_Size* aBlock = myNextAddr; @@ -362,10 +361,10 @@ Standard_Address Standard_MMgrOpt::Allocate(const Standard_Size aSize) const Standard_Size aPIndex = INDEX_CELL(aRPSize); if (aPIndex > 0 && aPIndex <= myFreeListMax) { - myMutex.Lock(); + myMutex.lock(); *(Standard_Size**)myNextAddr = myFreeList[aPIndex]; myFreeList[aPIndex] = myNextAddr; - myMutex.Unlock(); + myMutex.unlock(); } } @@ -391,7 +390,7 @@ Standard_Address Standard_MMgrOpt::Allocate(const Standard_Size aSize) else { // unlock the mutex immediately, as we do not need further to access any field - myMutex.Unlock(); + myMutex.unlock(); // we use operator ?: instead of if() since it is faster Standard_Size* aBlock = @@ -461,16 +460,14 @@ void Standard_MMgrOpt::Free(Standard_Address theStorage) // Note that we do not lock fields that do not change during the // object life (such as myThreshold), and assume that calls to functions // of standard library are already protected by their implementation. - // We also do not use Sentry, since in case if OCC signal or exception is - // caused by this block we will have deadlock anyway... - myMutex.Lock(); - - // in the memory block header, record address of the next free block - *(Standard_Size**)aBlock = myFreeList[Index]; - // add new block to be first in the list - myFreeList[Index] = aBlock; + { + std::lock_guard aLock(myMutex); - myMutex.Unlock(); + // in the memory block header, record address of the next free block + *(Standard_Size**)aBlock = myFreeList[Index]; + // add new block to be first in the list + myFreeList[Index] = aBlock; + } } // otherwise, we have block of big size which shall be simply released else @@ -485,7 +482,7 @@ void Standard_MMgrOpt::Free(Standard_Address theStorage) Standard_Integer Standard_MMgrOpt::Purge(Standard_Boolean) { // Lock access to critical data by mutex - Standard_Mutex::Sentry aSentry(myMutex); + std::lock_guard aLock(myMutex); // TODO: implement support for isDeleted = True @@ -507,7 +504,7 @@ Standard_Integer Standard_MMgrOpt::Purge(Standard_Boolean) } // Lock access to critical data by mutex - Standard_Mutex::Sentry aSentry1(myMutexPools); + std::lock_guard aLock1(myMutexPools); // release memory pools containing no busy memory; // for that for each pool count the summary size of blocks @@ -660,7 +657,7 @@ Standard_Integer Standard_MMgrOpt::Purge(Standard_Boolean) void Standard_MMgrOpt::FreePools() { // Lock access to critical data by mutex - Standard_Mutex::Sentry aSentry(myMutexPools); + std::lock_guard aLock(myMutexPools); // last pool is remembered in myAllocList Standard_Size* aFree = myAllocList; diff --git a/src/FoundationClasses/TKernel/Standard/Standard_MMgrOpt.hxx b/src/FoundationClasses/TKernel/Standard/Standard_MMgrOpt.hxx index acb6bfc534..3385de51e6 100644 --- a/src/FoundationClasses/TKernel/Standard/Standard_MMgrOpt.hxx +++ b/src/FoundationClasses/TKernel/Standard/Standard_MMgrOpt.hxx @@ -17,7 +17,8 @@ #define _Standard_MMgrOpt_HeaderFile #include -#include + +#include /** * @brief Open CASCADE memory manager optimized for speed. @@ -141,8 +142,8 @@ protected: // clang-format on Standard_Size myThreshold; //!< large block size - Standard_Mutex myMutex; //!< Mutex to protect free lists data - Standard_Mutex myMutexPools; //!< Mutex to protect small block pools data + std::mutex myMutex; //!< Mutex to protect free lists data + std::mutex myMutexPools; //!< Mutex to protect small block pools data }; #endif diff --git a/src/FoundationClasses/TKernel/Standard/Standard_StackTrace.cxx b/src/FoundationClasses/TKernel/Standard/Standard_StackTrace.cxx index 811c09e9bb..e0b614452a 100644 --- a/src/FoundationClasses/TKernel/Standard/Standard_StackTrace.cxx +++ b/src/FoundationClasses/TKernel/Standard/Standard_StackTrace.cxx @@ -15,7 +15,8 @@ #include #include -#include + +#include #include @@ -71,9 +72,9 @@ public: } //! Return global mutex. - static Standard_Mutex& Mutex() + static std::mutex& Mutex() { - static Standard_Mutex THE_MUTEX_LOCK; + static std::mutex THE_MUTEX_LOCK; return THE_MUTEX_LOCK; } @@ -234,8 +235,8 @@ Standard_Boolean Standard::StackTrace(char* theBuffer, } // DbgHelp is not thread-safe library, hence global lock is used for serial access - Standard_Mutex::Sentry aSentry(Standard_DbgHelper::Mutex()); - Standard_DbgHelper& aDbgHelp = Standard_DbgHelper::GetDbgHelper(); + std::lock_guard aLock(Standard_DbgHelper::Mutex()); + Standard_DbgHelper& aDbgHelp = Standard_DbgHelper::GetDbgHelper(); if (!aDbgHelp.IsLoaded()) { strcat_s(theBuffer, theBufferSize, "\n==Backtrace==\n"); diff --git a/src/FoundationClasses/TKernel/Standard/Standard_Type.cxx b/src/FoundationClasses/TKernel/Standard/Standard_Type.cxx index 1fd4a6defe..7aa0cc7d76 100644 --- a/src/FoundationClasses/TKernel/Standard/Standard_Type.cxx +++ b/src/FoundationClasses/TKernel/Standard/Standard_Type.cxx @@ -17,7 +17,8 @@ #include #include #include -#include + +#include IMPLEMENT_STANDARD_RTTIEXT(Standard_Type, Standard_Transient) @@ -115,8 +116,8 @@ Standard_Type* Standard_Type::Register(const std::type_info& theInfo, { // Access to registry is protected by mutex; it should not happen often because // instances are cached by Standard_Type::Instance() (one per binary module) - static Standard_Mutex aMutex; - Standard_Mutex::Sentry aSentry(aMutex); + static std::mutex aMutex; + std::lock_guard aLock(aMutex); // return existing descriptor if already in the registry registry_type& aRegistry = GetRegistry(); diff --git a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_2.cxx b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_2.cxx index 1f3e7e6844..3d77737a64 100644 --- a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_2.cxx +++ b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_2.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include //================================================================================================= diff --git a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_3.cxx b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_3.cxx index e6717298bb..70a61a6282 100644 --- a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_3.cxx +++ b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_3.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_4.cxx b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_4.cxx index fa5d071c17..a1d1e6b37a 100644 --- a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_4.cxx +++ b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_4.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_5.cxx b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_5.cxx index 8dfa3e944e..2f6cee3b55 100644 --- a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_5.cxx +++ b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_5.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index 7651e022ea..fe3e05a30a 100644 --- a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include diff --git a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_7.cxx b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_7.cxx index 06cba59e47..2bb1fb2e2e 100644 --- a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_7.cxx +++ b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_PaveFiller_7.cxx @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include diff --git a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_RemoveFeatures.cxx b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_RemoveFeatures.cxx index 8449da0bc7..bf9ff4d9f6 100644 --- a/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_RemoveFeatures.cxx +++ b/src/ModelingAlgorithms/TKBO/BOPAlgo/BOPAlgo_RemoveFeatures.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/src/ModelingAlgorithms/TKBO/BOPTools/BOPTools_Parallel.hxx b/src/ModelingAlgorithms/TKBO/BOPTools/BOPTools_Parallel.hxx index 0208d5c993..17a379941a 100644 --- a/src/ModelingAlgorithms/TKBO/BOPTools/BOPTools_Parallel.hxx +++ b/src/ModelingAlgorithms/TKBO/BOPTools/BOPTools_Parallel.hxx @@ -18,9 +18,10 @@ #include #include #include -#include #include +#include + //! Implementation of Functors/Starters class BOPTools_Parallel { @@ -82,7 +83,7 @@ class BOPTools_Parallel opencascade::handle aContext = new TypeContext(NCollection_BaseAllocator::CommonBaseAllocator()); - Standard_Mutex::Sentry aLocker(myMutex); + std::lock_guard aLock(myMutex); myContextMap.Bind(aThreadID, aContext); return myContextMap(aThreadID); } @@ -104,7 +105,7 @@ class BOPTools_Parallel private: TypeSolverVector& mySolverVector; mutable NCollection_DataMap> myContextMap; - mutable Standard_Mutex myMutex; + mutable std::mutex myMutex; }; //! Functor storing array of algorithm contexts per thread in pool diff --git a/src/ModelingAlgorithms/TKMesh/IMeshTools/IMeshTools_ModelAlgo.hxx b/src/ModelingAlgorithms/TKMesh/IMeshTools/IMeshTools_ModelAlgo.hxx index 09d731bb2d..02d0480ee7 100644 --- a/src/ModelingAlgorithms/TKMesh/IMeshTools/IMeshTools_ModelAlgo.hxx +++ b/src/ModelingAlgorithms/TKMesh/IMeshTools/IMeshTools_ModelAlgo.hxx @@ -17,6 +17,7 @@ #define _IMeshTools_ModelAlgo_HeaderFile #include +#include #include class IMeshData_Model; diff --git a/src/ModelingAlgorithms/TKShHealing/ShapeFix/ShapeFix_Wire_1.cxx b/src/ModelingAlgorithms/TKShHealing/ShapeFix/ShapeFix_Wire_1.cxx index a0363637ae..297446a071 100644 --- a/src/ModelingAlgorithms/TKShHealing/ShapeFix/ShapeFix_Wire_1.cxx +++ b/src/ModelingAlgorithms/TKShHealing/ShapeFix/ShapeFix_Wire_1.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/src/ModelingAlgorithms/TKShHealing/ShapeProcess/ShapeProcess_Context.cxx b/src/ModelingAlgorithms/TKShHealing/ShapeProcess/ShapeProcess_Context.cxx index 76b10617fe..bd56e12e7f 100644 --- a/src/ModelingAlgorithms/TKShHealing/ShapeProcess/ShapeProcess_Context.cxx +++ b/src/ModelingAlgorithms/TKShHealing/ShapeProcess/ShapeProcess_Context.cxx @@ -19,15 +19,23 @@ #include #include #include -#include #include #include #include +#include + #include IMPLEMENT_STANDARD_RTTIEXT(ShapeProcess_Context, Standard_Transient) -static Standard_Mutex THE_SHAPE_PROCESS_MUTEX; +namespace +{ +static std::mutex& GetShapeProcessMutex() +{ + static std::mutex THE_SHAPE_PROCESS_MUTEX; + return THE_SHAPE_PROCESS_MUTEX; +} +} // namespace //================================================================================================= @@ -74,7 +82,7 @@ Handle(Resource_Manager) ShapeProcess_Context::LoadResourceManager(const Standar { // Mutex is needed because we are initializing and changing static variables here, so // without mutex it leads to race condition. - Standard_Mutex::Sentry aLock(&THE_SHAPE_PROCESS_MUTEX); + std::lock_guard aLock(GetShapeProcessMutex()); // Optimisation of loading resource file: file is load only once // and reloaded only if file date has changed static Handle(Resource_Manager) sRC; diff --git a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Analyzer.cxx b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Analyzer.cxx index b9ff73bf0a..e034c2ccc7 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Analyzer.cxx +++ b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Analyzer.cxx @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,8 @@ #include #include +#include + //! Functor for multi-threaded execution. class BRepCheck_ParallelAnalyzer { @@ -166,7 +167,10 @@ public: if (performwire) { - Standard_Mutex::Sentry aLock(aFaceEdgeRes->GetMutex()); + std::unique_lock aLock = + aFaceEdgeRes->GetMutex() + ? std::unique_lock(*aFaceEdgeRes->GetMutex()) + : std::unique_lock(); if (aFaceEdgeRes->IsStatusOnShape(aShape)) { BRepCheck_ListIteratorOfListOfStatus itl(aFaceEdgeRes->StatusOnShape(aShape)); @@ -211,7 +215,9 @@ public: if (orientofwires) { - Standard_Mutex::Sentry aLock(aFaceWireRes->GetMutex()); + std::unique_lock aLock = + aFaceWireRes->GetMutex() ? std::unique_lock(*aFaceWireRes->GetMutex()) + : std::unique_lock(); if (aFaceWireRes->IsStatusOnShape(aShape)) { const BRepCheck_ListOfStatus& aStatusList = aFaceWireRes->StatusOnShape(aShape); diff --git a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Edge.cxx b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Edge.cxx index c0cfac0032..03bcaa011a 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Edge.cxx +++ b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Edge.cxx @@ -259,7 +259,8 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S) { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); if (myMap.IsBound(S)) { return; @@ -327,7 +328,7 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S) BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); constexpr Standard_Real eps = Precision::PConfusion(); - Standard_Boolean toRunParallel = !myMutex.IsNull(); + const Standard_Boolean toRunParallel = myMutex != nullptr; while (itcr.More()) { const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); @@ -571,7 +572,8 @@ Standard_Boolean BRepCheck_Edge::GeometricControls() const void BRepCheck_Edge::SetStatus(const BRepCheck_Status theStatus) { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); BRepCheck::Add(*myMap(myShape), theStatus); } diff --git a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Face.cxx b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Face.cxx index 3b2d62fd2a..23f251018f 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Face.cxx +++ b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Face.cxx @@ -115,7 +115,8 @@ void BRepCheck_Face::InContext(const TopoDS_Shape& S) { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); if (myMap.IsBound(S)) { return; @@ -163,7 +164,8 @@ BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update) { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); aHList = myMap(myShape); } @@ -292,7 +294,8 @@ BRepCheck_Status BRepCheck_Face::ClassifyWires(const Standard_Boolean Update) { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); aHList = myMap(myShape); } @@ -420,7 +423,8 @@ BRepCheck_Status BRepCheck_Face::OrientationOfWires(const Standard_Boolean Updat { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); aHList = myMap(myShape); } @@ -535,7 +539,8 @@ BRepCheck_Status BRepCheck_Face::OrientationOfWires(const Standard_Boolean Updat void BRepCheck_Face::SetUnorientable() { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); BRepCheck::Add(*myMap(myShape), BRepCheck_UnorientableShape); } @@ -543,7 +548,8 @@ void BRepCheck_Face::SetUnorientable() void BRepCheck_Face::SetStatus(const BRepCheck_Status theStatus) { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); BRepCheck::Add(*myMap(myShape), theStatus); } diff --git a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Result.cxx b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Result.cxx index d753758c7c..c28db7b81c 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Result.cxx +++ b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Result.cxx @@ -46,7 +46,8 @@ void BRepCheck_Result::Init(const TopoDS_Shape& S) void BRepCheck_Result::SetFailStatus(const TopoDS_Shape& S) { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); Handle(BRepCheck_HListOfStatus) aList; if (!myMap.Find(S, aList)) { @@ -84,8 +85,8 @@ void BRepCheck_Result::NextShapeInContext() void BRepCheck_Result::SetParallel(Standard_Boolean theIsParallel) { - if (theIsParallel && myMutex.IsNull()) + if (theIsParallel && !myMutex) { - myMutex.reset(new Standard_HMutex()); + myMutex = opencascade::make_unique(); } } diff --git a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Result.hxx b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Result.hxx index 022e0108eb..4f9d71c9f0 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Result.hxx +++ b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Result.hxx @@ -19,10 +19,12 @@ #include -#include #include #include #include +#include + +#include DEFINE_STANDARD_HANDLE(BRepCheck_Result, Standard_Transient) @@ -80,10 +82,10 @@ protected: Standard_Boolean myMin; Standard_Boolean myBlind; BRepCheck_DataMapOfShapeListOfStatus myMap; - mutable Handle(Standard_HMutex) myMutex; + mutable std::unique_ptr myMutex; private: - Standard_HMutex* GetMutex() { return myMutex.get(); } + std::unique_ptr& GetMutex() { return myMutex; } private: BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus myIter; diff --git a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Shell.cxx b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Shell.cxx index 1914de42b2..c604ed5312 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Shell.cxx +++ b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Shell.cxx @@ -177,7 +177,8 @@ void BRepCheck_Shell::InContext(const TopoDS_Shape& S) { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); if (myMap.IsBound(S)) { return; @@ -247,7 +248,8 @@ BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update) { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); aHList = myMap(myShape); } @@ -429,7 +431,8 @@ BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update) { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); aHList = myMap(myShape); } BRepCheck_ListOfStatus& aStatusList = *aHList; @@ -826,7 +829,8 @@ BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update) void BRepCheck_Shell::SetUnorientable() { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); BRepCheck::Add(*myMap(myShape), BRepCheck_UnorientableShape); } @@ -841,7 +845,8 @@ Standard_Boolean BRepCheck_Shell::IsUnorientable() const Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); aHList = myMap(myShape); } BRepCheck_ListOfStatus& aStatusList = *aHList; diff --git a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Vertex.cxx b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Vertex.cxx index 4f9c5391d4..59dfa086bd 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Vertex.cxx +++ b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Vertex.cxx @@ -64,7 +64,8 @@ void BRepCheck_Vertex::InContext(const TopoDS_Shape& S) { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); if (myMap.IsBound(S)) { return; diff --git a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Wire.cxx b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Wire.cxx index 60a4ec2297..e3a4a895e3 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Wire.cxx +++ b/src/ModelingAlgorithms/TKTopAlgo/BRepCheck/BRepCheck_Wire.cxx @@ -187,7 +187,8 @@ void BRepCheck_Wire::InContext(const TopoDS_Shape& S) { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); if (myMap.IsBound(S)) { return; @@ -273,7 +274,8 @@ BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update) { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); aHList = myMap(myShape); } @@ -540,7 +542,8 @@ BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace, const Stan { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); aHList = myMap(myShape); } BRepCheck_ListOfStatus& aStatusList = *aHList; @@ -717,7 +720,8 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F, const Standar BRepCheck_Status theOstat = Closed(); Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); aHList = myMap(myShape); } BRepCheck_ListOfStatus& aStatusList = *aHList; @@ -1057,7 +1061,8 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F, { Handle(BRepCheck_HListOfStatus) aHList; { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::unique_lock aLock = + myMutex ? std::unique_lock(*myMutex) : std::unique_lock(); aHList = myMap(myShape); } BRepCheck_ListOfStatus& aStatusList = *aHList; diff --git a/src/ModelingAlgorithms/TKTopAlgo/BRepExtrema/BRepExtrema_DistShapeShape.cxx b/src/ModelingAlgorithms/TKTopAlgo/BRepExtrema/BRepExtrema_DistShapeShape.cxx index 4e6b8188c9..d9a678b0bd 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/BRepExtrema/BRepExtrema_DistShapeShape.cxx +++ b/src/ModelingAlgorithms/TKTopAlgo/BRepExtrema/BRepExtrema_DistShapeShape.cxx @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,8 @@ #include #include +#include +#include namespace { @@ -696,7 +699,7 @@ struct TreatmentFunctor DistRef(0), InnerSol(NULL), IsDone(NULL), - Mutex(NULL) + Mutex() { for (Standard_Integer i = 0; i < theArrayOfArrays->Size(); ++i) { @@ -717,7 +720,7 @@ struct TreatmentFunctor break; } aScope.Next(); - if (*IsDone) + if (IsDone->load(std::memory_order_acquire)) { break; } @@ -727,10 +730,11 @@ struct TreatmentFunctor aClassifier.Perform(aPnt, aTolerance); if (aClassifier.State() == TopAbs_IN) { - Standard_Mutex::Sentry aLock(Mutex.get()); - *InnerSol = Standard_True; - *DistRef = 0.; - *IsDone = Standard_True; + std::unique_lock aLock = + Mutex ? std::unique_lock(*Mutex) : std::unique_lock(); + InnerSol->store(true, std::memory_order_release); + *DistRef = 0.; + IsDone->store(true, std::memory_order_release); BRepExtrema_SolutionElem aSolElem(0, aPnt, BRepExtrema_IsVertex, aVertex); SolutionsShape1->Append(aSolElem); SolutionsShape2->Append(aSolElem); @@ -746,9 +750,9 @@ struct TreatmentFunctor Message_ProgressScope Scope; NCollection_Array1 Ranges; Standard_Real* DistRef; - volatile Standard_Boolean* InnerSol; - volatile Standard_Boolean* IsDone; - Handle(Standard_HMutex) Mutex; + std::atomic* InnerSol; + std::atomic* IsDone; + std::unique_ptr Mutex; }; //================================================================================================= @@ -788,21 +792,29 @@ Standard_Boolean BRepExtrema_DistShapeShape::SolidTreatment( anArrayOfArray[aVectIndex][aShapeIndex] = theVertexMap(anI); } + // Create local atomic variables for thread-safe communication during parallel section + std::atomic anAtomicInnerSol(myInnerSol); + std::atomic anAtomicIsDone(myIsDone); + Message_ProgressScope aScope(theRange, "Solid treatment", aNbTasks); TreatmentFunctor aFunctor(&anArrayOfArray, aScope.Next()); aFunctor.SolutionsShape1 = &mySolutionsShape1; aFunctor.SolutionsShape2 = &mySolutionsShape2; aFunctor.Shape = theShape; aFunctor.DistRef = &myDistRef; - aFunctor.InnerSol = &myInnerSol; - aFunctor.IsDone = &myIsDone; - if (myIsMultiThread) + aFunctor.InnerSol = &anAtomicInnerSol; + aFunctor.IsDone = &anAtomicIsDone; + if (myIsMultiThread && !aFunctor.Mutex) { - aFunctor.Mutex.reset(new Standard_HMutex()); + aFunctor.Mutex = std::make_unique(); } OSD_Parallel::For(0, aNbTasks, aFunctor, !myIsMultiThread); + // Copy atomic results back to class members after parallel section completes + myInnerSol = anAtomicInnerSol.load(std::memory_order_acquire); + myIsDone = anAtomicIsDone.load(std::memory_order_acquire); + if (!aScope.More()) { return Standard_False; diff --git a/src/ModelingData/TKBRep/BinTools/BinTools_ShapeReader.cxx b/src/ModelingData/TKBRep/BinTools/BinTools_ShapeReader.cxx index 1f9638e82f..8ed9141000 100644 --- a/src/ModelingData/TKBRep/BinTools/BinTools_ShapeReader.cxx +++ b/src/ModelingData/TKBRep/BinTools/BinTools_ShapeReader.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include //================================================================================================= diff --git a/src/ModelingData/TKBRep/BinTools/BinTools_ShapeWriter.cxx b/src/ModelingData/TKBRep/BinTools/BinTools_ShapeWriter.cxx index 392a1d4d12..9a85e68c07 100644 --- a/src/ModelingData/TKBRep/BinTools/BinTools_ShapeWriter.cxx +++ b/src/ModelingData/TKBRep/BinTools/BinTools_ShapeWriter.cxx @@ -29,6 +29,7 @@ #include #include #include +#include //================================================================================================= diff --git a/src/ModelingData/TKBRep/TopTools/FILES.cmake b/src/ModelingData/TKBRep/TopTools/FILES.cmake index e01d90f0c5..efb9e56f0c 100644 --- a/src/ModelingData/TKBRep/TopTools/FILES.cmake +++ b/src/ModelingData/TKBRep/TopTools/FILES.cmake @@ -49,8 +49,6 @@ set(OCCT_TopTools_FILES TopTools_MapIteratorOfMapOfShape.hxx TopTools_MapOfOrientedShape.hxx TopTools_MapOfShape.hxx - TopTools_MutexForShapeProvider.cxx - TopTools_MutexForShapeProvider.hxx TopTools_SequenceOfShape.hxx TopTools_ShapeMapHasher.hxx TopTools_ShapeSet.cxx diff --git a/src/ModelingData/TKBRep/TopTools/TopTools_MutexForShapeProvider.cxx b/src/ModelingData/TKBRep/TopTools/TopTools_MutexForShapeProvider.cxx deleted file mode 100644 index d095118af6..0000000000 --- a/src/ModelingData/TKBRep/TopTools/TopTools_MutexForShapeProvider.cxx +++ /dev/null @@ -1,94 +0,0 @@ -// Created on: 2012-06-27 -// Created by: Dmitry BOBYLEV -// Copyright (c) 2012-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include - -#include -#include - -// macro to compare two types of shapes -#define SAMETYPE(x, y) ((x) == (y)) -#define LESSCOMPLEX(x, y) ((x) > (y)) - -//================================================================================================= - -TopTools_MutexForShapeProvider::TopTools_MutexForShapeProvider() {} - -//================================================================================================= - -TopTools_MutexForShapeProvider::~TopTools_MutexForShapeProvider() -{ - RemoveAllMutexes(); -} - -//================================================================================================= - -void TopTools_MutexForShapeProvider::CreateMutexesForSubShapes(const TopoDS_Shape& theShape, - const TopAbs_ShapeEnum theType) -{ - if (LESSCOMPLEX(theShape.ShapeType(), theType)) - return; - - for (TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next()) - { - const TopoDS_Shape& aShape = anIt.Value(); - if (LESSCOMPLEX(theType, aShape.ShapeType())) - { - CreateMutexesForSubShapes(aShape, theType); - } - else if (SAMETYPE(theType, aShape.ShapeType())) - { - CreateMutexForShape(aShape); - } - } -} - -//================================================================================================= - -void TopTools_MutexForShapeProvider::CreateMutexForShape(const TopoDS_Shape& theShape) -{ - if (!myMap.IsBound(theShape.TShape())) - { - Standard_Mutex* aMutex = new Standard_Mutex(); - myMap.Bind(theShape.TShape(), aMutex); - } -} - -//================================================================================================= - -Standard_Mutex* TopTools_MutexForShapeProvider::GetMutex(const TopoDS_Shape& theShape) const -{ - if (myMap.IsBound(theShape.TShape())) - { - Standard_Mutex* aMutex = myMap.Find(theShape.TShape()); - return aMutex; - } - else - { - return NULL; - } -} - -//================================================================================================= - -void TopTools_MutexForShapeProvider::RemoveAllMutexes() -{ - for (NCollection_DataMap::Iterator anIter; anIter.More(); - anIter.Next()) - { - delete anIter.Value(); - } - myMap.Clear(); -} diff --git a/src/ModelingData/TKBRep/TopTools/TopTools_MutexForShapeProvider.hxx b/src/ModelingData/TKBRep/TopTools/TopTools_MutexForShapeProvider.hxx deleted file mode 100644 index 63c9632f77..0000000000 --- a/src/ModelingData/TKBRep/TopTools/TopTools_MutexForShapeProvider.hxx +++ /dev/null @@ -1,60 +0,0 @@ -// Created on: 2012-06-27 -// Created by: Dmitry BOBYLEV -// Copyright (c) 2012-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _TopTools_MutexForShapeProvider_HeaderFile -#define _TopTools_MutexForShapeProvider_HeaderFile - -#include -#include -#include - -class Standard_Mutex; -class TopoDS_Shape; - -//! Class TopTools_MutexForShapeProvider -//! This class is used to create and store mutexes associated with shapes. -class TopTools_MutexForShapeProvider -{ -public: - //! Constructor - Standard_EXPORT TopTools_MutexForShapeProvider(); - - //! Destructor - Standard_EXPORT ~TopTools_MutexForShapeProvider(); - - //! Creates and associates mutexes with each sub-shape of type theType in theShape. - Standard_EXPORT void CreateMutexesForSubShapes(const TopoDS_Shape& theShape, - const TopAbs_ShapeEnum theType); - - //! Creates and associates mutex with theShape - Standard_EXPORT void CreateMutexForShape(const TopoDS_Shape& theShape); - - //! Returns pointer to mutex associated with theShape. - //! In case when mutex not found returns NULL. - Standard_EXPORT Standard_Mutex* GetMutex(const TopoDS_Shape& theShape) const; - - //! Removes all mutexes - Standard_EXPORT void RemoveAllMutexes(); - -private: - //! This method should not be called (prohibited). - TopTools_MutexForShapeProvider(const TopTools_MutexForShapeProvider&); - //! This method should not be called (prohibited). - TopTools_MutexForShapeProvider& operator=(const TopTools_MutexForShapeProvider&); - - NCollection_DataMap myMap; -}; - -#endif diff --git a/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface_1.cxx b/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface_1.cxx index b7ba56275c..ce348a53a3 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface_1.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface_1.cxx @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/src/Visualization/TKService/Aspect/Aspect_VKeySet.cxx b/src/Visualization/TKService/Aspect/Aspect_VKeySet.cxx index 48d7301a6d..3a9d4b3c7d 100644 --- a/src/Visualization/TKService/Aspect/Aspect_VKeySet.cxx +++ b/src/Visualization/TKService/Aspect/Aspect_VKeySet.cxx @@ -28,7 +28,7 @@ Aspect_VKeySet::Aspect_VKeySet() void Aspect_VKeySet::Reset() { - Standard_Mutex::Sentry aLock(myLock); + std::lock_guard aLock(myLock); myModifiers = 0; for (NCollection_Array1::Iterator aKeyIter(myKeys); aKeyIter.More(); aKeyIter.Next()) { @@ -38,9 +38,8 @@ void Aspect_VKeySet::Reset() //================================================================================================= -void Aspect_VKeySet::KeyDown(Aspect_VKey theKey, double theTime, double thePressure) +void Aspect_VKeySet::KeyDown_Unlocked(Aspect_VKey theKey, double theTime, double thePressure) { - Standard_Mutex::Sentry aLock(myLock); if (myKeys[theKey].KStatus != KeyStatus_Pressed) { myKeys[theKey].KStatus = KeyStatus_Pressed; @@ -54,9 +53,16 @@ void Aspect_VKeySet::KeyDown(Aspect_VKey theKey, double theTime, double thePress //================================================================================================= -void Aspect_VKeySet::KeyUp(Aspect_VKey theKey, double theTime) +void Aspect_VKeySet::KeyDown(Aspect_VKey theKey, double theTime, double thePressure) +{ + std::lock_guard aLock(myLock); + KeyDown_Unlocked(theKey, theTime, thePressure); +} + +//================================================================================================= + +void Aspect_VKeySet::KeyUp_Unlocked(Aspect_VKey theKey, double theTime) { - Standard_Mutex::Sentry aLock(myLock); if (myKeys[theKey].KStatus == KeyStatus_Pressed) { myKeys[theKey].KStatus = KeyStatus_Released; @@ -72,32 +78,40 @@ void Aspect_VKeySet::KeyUp(Aspect_VKey theKey, double theTime) //================================================================================================= +void Aspect_VKeySet::KeyUp(Aspect_VKey theKey, double theTime) +{ + std::lock_guard aLock(myLock); + KeyUp_Unlocked(theKey, theTime); +} + +//================================================================================================= + void Aspect_VKeySet::KeyFromAxis(Aspect_VKey theNegative, Aspect_VKey thePositive, double theTime, double thePressure) { - Standard_Mutex::Sentry aLock(myLock); + std::lock_guard aLock(myLock); if (thePressure != 0) { const Aspect_VKey aKeyDown = thePressure > 0 ? thePositive : theNegative; const Aspect_VKey aKeyUp = thePressure < 0 ? thePositive : theNegative; - KeyDown(aKeyDown, theTime, Abs(thePressure)); + KeyDown_Unlocked(aKeyDown, theTime, Abs(thePressure)); if (myKeys[aKeyUp].KStatus == KeyStatus_Pressed) { - KeyUp(aKeyUp, theTime); + KeyUp_Unlocked(aKeyUp, theTime); } } else { if (myKeys[theNegative].KStatus == KeyStatus_Pressed) { - KeyUp(theNegative, theTime); + KeyUp_Unlocked(theNegative, theTime); } if (myKeys[thePositive].KStatus == KeyStatus_Pressed) { - KeyUp(thePositive, theTime); + KeyUp_Unlocked(thePositive, theTime); } } } @@ -109,7 +123,7 @@ bool Aspect_VKeySet::HoldDuration(Aspect_VKey theKey, double& theDuration, double& thePressure) { - Standard_Mutex::Sentry aLock(myLock); + std::lock_guard aLock(myLock); switch (myKeys[theKey].KStatus) { case KeyStatus_Free: { diff --git a/src/Visualization/TKService/Aspect/Aspect_VKeySet.hxx b/src/Visualization/TKService/Aspect/Aspect_VKeySet.hxx index eceeb1cae2..53939cfc39 100644 --- a/src/Visualization/TKService/Aspect/Aspect_VKeySet.hxx +++ b/src/Visualization/TKService/Aspect/Aspect_VKeySet.hxx @@ -18,9 +18,10 @@ #include #include -#include #include +#include + //! Structure defining key state. class Aspect_VKeySet : public Standard_Transient { @@ -32,42 +33,42 @@ public: //! Return active modifiers. Aspect_VKeyFlags Modifiers() const { - Standard_Mutex::Sentry aLock(myLock); + std::shared_lock aLock(myLock); return myModifiers; } //! Return timestamp of press event. double DownTime(Aspect_VKey theKey) const { - Standard_Mutex::Sentry aLock(myLock); + std::shared_lock aLock(myLock); return myKeys[theKey].TimeDown; } //! Return timestamp of release event. double TimeUp(Aspect_VKey theKey) const { - Standard_Mutex::Sentry aLock(myLock); + std::shared_lock aLock(myLock); return myKeys[theKey].TimeUp; } //! Return TRUE if key is in Free state. bool IsFreeKey(Aspect_VKey theKey) const { - Standard_Mutex::Sentry aLock(myLock); + std::shared_lock aLock(myLock); return myKeys[theKey].KStatus == KeyStatus_Free; } //! Return TRUE if key is in Pressed state. bool IsKeyDown(Aspect_VKey theKey) const { - Standard_Mutex::Sentry aLock(myLock); + std::shared_lock aLock(myLock); return myKeys[theKey].KStatus == KeyStatus_Pressed; } //! Return mutex for thread-safe updates. //! All operations in class implicitly locks this mutex, //! so this method could be used only for batch processing of keys. - Standard_Mutex& Mutex() { return myLock; } + std::shared_mutex& Mutex() { return myLock; } public: //! Reset the key state into unpressed state. @@ -111,6 +112,13 @@ public: double& theDuration, double& thePressure); +private: + //! Press key without locking (assumes lock is already held). + void KeyDown_Unlocked(Aspect_VKey theKey, double theTime, double thePressure); + + //! Release key without locking (assumes lock is already held). + void KeyUp_Unlocked(Aspect_VKey theKey, double theTime); + private: //! Key state. enum KeyStatus @@ -147,7 +155,7 @@ private: private: NCollection_Array1 myKeys; //!< keys state - mutable Standard_Mutex myLock; //!< mutex for thread-safe updates + mutable std::shared_mutex myLock; //!< mutex for thread-safe updates Aspect_VKeyFlags myModifiers; //!< active modifiers }; diff --git a/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTexture.cxx b/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTexture.cxx index 0f47156e57..b01e965fe2 100644 --- a/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTexture.cxx +++ b/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTexture.cxx @@ -38,8 +38,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_MediaTexture, Graphic3d_Texture2D) //================================================================================================= -Graphic3d_MediaTexture::Graphic3d_MediaTexture(const Handle(Standard_HMutex)& theMutex, - Standard_Integer thePlane) +Graphic3d_MediaTexture::Graphic3d_MediaTexture(std::mutex& theMutex, Standard_Integer thePlane) : Graphic3d_Texture2D("", Graphic3d_TypeOfTexture_2D), myMutex(theMutex), myPlane(thePlane) @@ -54,7 +53,8 @@ Graphic3d_MediaTexture::Graphic3d_MediaTexture(const Handle(Standard_HMutex)& th Handle(Image_PixMap) Graphic3d_MediaTexture::GetImage(const Handle(Image_SupportedFormats)&) { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::lock_guard aLock(myMutex); + if (myFrame.IsNull() || myFrame->IsLocked() || myFrame->IsEmpty() || myFrame->SizeX() < 1 || myFrame->SizeY() < 1) { diff --git a/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTexture.hxx b/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTexture.hxx index 8584e33717..8b9ec55857 100644 --- a/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTexture.hxx +++ b/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTexture.hxx @@ -16,7 +16,8 @@ #define _Graphic3d_MediaTexture_HeaderFile #include -#include + +#include class Media_Frame; @@ -25,10 +26,6 @@ class Graphic3d_MediaTexture : public Graphic3d_Texture2D { DEFINE_STANDARD_RTTIEXT(Graphic3d_MediaTexture, Graphic3d_Texture2D) public: - //! Main constructor. - Standard_EXPORT Graphic3d_MediaTexture(const Handle(Standard_HMutex)& theMutex, - Standard_Integer thePlane = -1); - //! Image reader. Standard_EXPORT virtual Handle(Image_PixMap) GetImage( const Handle(Image_SupportedFormats)& theSupported) Standard_OVERRIDE; @@ -42,11 +39,18 @@ public: //! Regenerate a new texture id void GenerateNewId() { generateId(); } + friend class Graphic3d_MediaTextureSet; + +private: + //! Main constructor. + //! Accessible only by Graphic3d_MediaTextureSet. + Standard_EXPORT Graphic3d_MediaTexture(std::mutex& theMutex, Standard_Integer thePlane = -1); + protected: - mutable Handle(Standard_HMutex) myMutex; - Handle(Media_Frame) myFrame; - Standard_Integer myPlane; - mutable Handle(Image_PixMap) myPixMapWrapper; + std::mutex& myMutex; + Handle(Media_Frame) myFrame; + Standard_Integer myPlane; + mutable Handle(Image_PixMap) myPixMapWrapper; }; #endif // _Graphic3d_MediaTexture_HeaderFile diff --git a/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTextureSet.cxx b/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTextureSet.cxx index 212bef5d19..f1af800ada 100644 --- a/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTextureSet.cxx +++ b/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTextureSet.cxx @@ -39,7 +39,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_MediaTextureSet, Graphic3d_TextureSet) Graphic3d_MediaTextureSet::Graphic3d_MediaTextureSet() : Graphic3d_TextureSet(4), - myMutex(new Standard_HMutex()), + myMutex(), myCallbackFunction(NULL), myCallbackUserPtr(NULL), myProgress(0.0), @@ -156,7 +156,7 @@ void Graphic3d_MediaTextureSet::OpenInput(const TCollection_AsciiString& thePath Handle(Media_Frame) Graphic3d_MediaTextureSet::LockFrame() { { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::lock_guard aLock(myMutex); if (!myToPresentFrame) { Handle(Media_Frame) aFrame = myFramePair[myFront == 0 ? 1 : 0]; @@ -179,7 +179,8 @@ Handle(Media_Frame) Graphic3d_MediaTextureSet::LockFrame() void Graphic3d_MediaTextureSet::ReleaseFrame(const Handle(Media_Frame)& theFrame) { { - Standard_Mutex::Sentry aLock(myMutex.get()); + std::lock_guard aLock(myMutex); + theFrame->SetLocked(false); myToPresentFrame = true; } @@ -201,7 +202,7 @@ Standard_Boolean Graphic3d_MediaTextureSet::SwapFrames() Standard_Boolean isPaused = Standard_False; myPlayerCtx->PlaybackState(isPaused, myProgress, myDuration); - Standard_Mutex::Sentry aLock(myMutex.get()); + std::lock_guard aLock(myMutex); if (!myToPresentFrame) { return Standard_False; diff --git a/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTextureSet.hxx b/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTextureSet.hxx index 31bd32f03f..7693023c36 100644 --- a/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTextureSet.hxx +++ b/src/Visualization/TKService/Graphic3d/Graphic3d_MediaTextureSet.hxx @@ -19,6 +19,8 @@ #include #include +#include + class Graphic3d_ShaderProgram; class Media_PlayerContext; @@ -93,7 +95,7 @@ protected: Handle(Media_Frame) myFramePair[2]; //!< front/back frames pair Handle(Graphic3d_ShaderProgram) myShaderYUV; //!< shader program for YUV texture set Handle(Graphic3d_ShaderProgram) myShaderYUVJ; //!< shader program for YUVJ texture set - Handle(Standard_HMutex) myMutex; //!< mutex for accessing frames + std::mutex myMutex; //!< mutex for accessing frames TCollection_AsciiString myInput; //!< input media CallbackOnUpdate_t myCallbackFunction; //!< callback function void* myCallbackUserPtr; //!< callback data diff --git a/src/Visualization/TKService/Media/Media_PlayerContext.cxx b/src/Visualization/TKService/Media/Media_PlayerContext.cxx index 99392798de..1680284788 100644 --- a/src/Visualization/TKService/Media/Media_PlayerContext.cxx +++ b/src/Visualization/TKService/Media/Media_PlayerContext.cxx @@ -225,7 +225,7 @@ void Media_PlayerContext::SetInput(const TCollection_AsciiString& theInputPath, Standard_Boolean theToWait) { { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); if (theToWait) { myNextEvent.Reset(); @@ -246,7 +246,7 @@ void Media_PlayerContext::PlaybackState(Standard_Boolean& theIsPaused, Standard_Real& theProgress, Standard_Real& theDuration) { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); theIsPaused = !myTimer.IsStarted(); theProgress = myTimer.ElapsedTime(); theDuration = myDuration; @@ -258,7 +258,7 @@ void Media_PlayerContext::PlayPause(Standard_Boolean& theIsPaused, Standard_Real& theProgress, Standard_Real& theDuration) { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); theProgress = myTimer.ElapsedTime(); theDuration = myDuration; if (myTimer.IsStarted()) @@ -277,16 +277,32 @@ void Media_PlayerContext::PlayPause(Standard_Boolean& theIsPaused, void Media_PlayerContext::Seek(Standard_Real thePosSec) { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); mySeekTo = thePosSec; pushPlayEvent(Media_PlayerEvent_SEEK); } //================================================================================================= +void Media_PlayerContext::Pause() +{ + std::lock_guard aLock(myMutex); + pushPlayEvent(Media_PlayerEvent_PAUSE); +} + +//================================================================================================= + +void Media_PlayerContext::Resume() +{ + std::lock_guard aLock(myMutex); + pushPlayEvent(Media_PlayerEvent_RESUME); +} + +//================================================================================================= + void Media_PlayerContext::pushPlayEvent(Media_PlayerEvent thePlayEvent) { - Standard_Mutex::Sentry aLock(myMutex); + // NOTE: Caller must hold myMutex lock before calling this method myPlayEvent = thePlayEvent; myWakeEvent.Set(); } @@ -304,7 +320,7 @@ bool Media_PlayerContext::popPlayEvent(Media_PlayerEvent& thePla return false; } - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); thePlayEvent = myPlayEvent; if (thePlayEvent == Media_PlayerEvent_PAUSE) { @@ -495,7 +511,7 @@ void Media_PlayerContext::doThreadLoop() TCollection_AsciiString anInput; { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); std::swap(anInput, myInputPath); if (myPlayEvent == Media_PlayerEvent_NEXT) { @@ -543,7 +559,7 @@ void Media_PlayerContext::doThreadLoop() Handle(Media_Packet) aPacket = new Media_Packet(); Media_PlayerEvent aPlayEvent = Media_PlayerEvent_NONE; { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); myTimer.Stop(); myTimer.Start(); myDuration = aFormatCtx->Duration(); diff --git a/src/Visualization/TKService/Media/Media_PlayerContext.hxx b/src/Visualization/TKService/Media/Media_PlayerContext.hxx index 9e5bf46c27..9019a4abd4 100644 --- a/src/Visualization/TKService/Media/Media_PlayerContext.hxx +++ b/src/Visualization/TKService/Media/Media_PlayerContext.hxx @@ -19,11 +19,12 @@ #include #include #include -#include #include #include #include +#include + class Media_BufferPool; class Media_CodecContext; class Media_FormatContext; @@ -79,10 +80,10 @@ public: Standard_EXPORT void Seek(Standard_Real thePosSec); //! Pause playback. - void Pause() { pushPlayEvent(Media_PlayerEvent_PAUSE); } + Standard_EXPORT void Pause(); //! Resume playback. - void Resume() { pushPlayEvent(Media_PlayerEvent_RESUME); } + Standard_EXPORT void Resume(); //! Return TRUE if queue requires RGB pixel format or can handle also YUV pixel format; TRUE by //! default. @@ -130,7 +131,7 @@ private: private: Media_IFrameQueue* myFrameQueue; //!< frame queue OSD_Thread myThread; //!< working thread - Standard_Mutex myMutex; //!< mutex for events + std::mutex myMutex; //!< mutex for events // clang-format off Standard_Condition myWakeEvent; //!< event to wake up working thread and proceed new playback event Standard_Condition myNextEvent; //!< event to check if working thread processed next file event (e.g. released file handles of previous input) diff --git a/src/Visualization/TKV3d/AIS/AIS_ViewController.cxx b/src/Visualization/TKV3d/AIS/AIS_ViewController.cxx index 5cf03ae562..d4ab549065 100644 --- a/src/Visualization/TKV3d/AIS/AIS_ViewController.cxx +++ b/src/Visualization/TKV3d/AIS/AIS_ViewController.cxx @@ -2067,9 +2067,8 @@ void AIS_ViewController::handleViewOrientationKeys(const Handle(AIS_InteractiveC {Aspect_VKey_ViewRoll90CCW, (V3d_TypeOfOrientation)-1}, {Aspect_VKey_ViewFitAll, (V3d_TypeOfOrientation)-1}}; { - Standard_Mutex::Sentry aLock(myKeys.Mutex()); - const size_t aNbKeys = sizeof(THE_VIEW_KEYS) / sizeof(*THE_VIEW_KEYS); - const double anEventTime = EventTime(); + const size_t aNbKeys = sizeof(THE_VIEW_KEYS) / sizeof(*THE_VIEW_KEYS); + const double anEventTime = EventTime(); for (size_t aKeyIter = 0; aKeyIter < aNbKeys; ++aKeyIter) { const ViewKeyAction& aKeyAction = THE_VIEW_KEYS[aKeyIter]; diff --git a/src/Visualization/TKV3d/AIS/AIS_ViewController.hxx b/src/Visualization/TKV3d/AIS/AIS_ViewController.hxx index f582c34b6f..f84996b4d5 100644 --- a/src/Visualization/TKV3d/AIS/AIS_ViewController.hxx +++ b/src/Visualization/TKV3d/AIS/AIS_ViewController.hxx @@ -31,7 +31,6 @@ #include #include #include -#include class AIS_Animation; class AIS_AnimationCamera; diff --git a/src/Visualization/TKV3d/Select3D/Select3D_SensitivePrimitiveArray.hxx b/src/Visualization/TKV3d/Select3D/Select3D_SensitivePrimitiveArray.hxx index 942a2198ab..06d91ab13e 100644 --- a/src/Visualization/TKV3d/Select3D/Select3D_SensitivePrimitiveArray.hxx +++ b/src/Visualization/TKV3d/Select3D/Select3D_SensitivePrimitiveArray.hxx @@ -21,6 +21,8 @@ #include #include #include +#include +#include //! Sensitive for triangulation or point set defined by Primitive Array. //! The primitives can be optionally combined into patches within BVH tree diff --git a/src/Visualization/TKV3d/SelectMgr/SelectMgr_BVHThreadPool.cxx b/src/Visualization/TKV3d/SelectMgr/SelectMgr_BVHThreadPool.cxx index 1d12d7e395..2bdd71ae82 100644 --- a/src/Visualization/TKV3d/SelectMgr/SelectMgr_BVHThreadPool.cxx +++ b/src/Visualization/TKV3d/SelectMgr/SelectMgr_BVHThreadPool.cxx @@ -12,9 +12,11 @@ // commercial license or contractual agreement. #include + #include #include #include +#include IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_BVHThreadPool, Standard_Transient) @@ -84,7 +86,7 @@ void SelectMgr_BVHThreadPool::AddEntity(const Handle(Select3D_SensitiveEntity)& } { - Standard_Mutex::Sentry aSentry(myBVHListMutex); + std::lock_guard aLock(myBVHListMutex); myBVHToBuildList.Append(theEntity); myWakeEvent.Set(); myIdleEvent.Reset(); @@ -115,19 +117,21 @@ void SelectMgr_BVHThreadPool::BVHThread::performThread() return; } - myPool->myBVHListMutex.Lock(); - if (myPool->myBVHToBuildList.IsEmpty()) + Handle(Select3D_SensitiveEntity) anEntity; { - myPool->myWakeEvent.Reset(); - myPool->myIdleEvent.Set(); - myPool->myBVHListMutex.Unlock(); - continue; + std::lock_guard aListLock(myPool->myBVHListMutex); + if (myPool->myBVHToBuildList.IsEmpty()) + { + myPool->myWakeEvent.Reset(); + myPool->myIdleEvent.Set(); + continue; + } + anEntity = myPool->myBVHToBuildList.First(); + myPool->myBVHToBuildList.RemoveFirst(); } - Handle(Select3D_SensitiveEntity) anEntity = myPool->myBVHToBuildList.First(); - myPool->myBVHToBuildList.RemoveFirst(); - Standard_Mutex::Sentry anEntry(myMutex); - myPool->myBVHListMutex.Unlock(); + // Lock thread mutex while building BVH + std::lock_guard aThreadLock(myMutex); if (!anEntity.IsNull()) { diff --git a/src/Visualization/TKV3d/SelectMgr/SelectMgr_BVHThreadPool.hxx b/src/Visualization/TKV3d/SelectMgr/SelectMgr_BVHThreadPool.hxx index 2154155ebe..b733314fdd 100644 --- a/src/Visualization/TKV3d/SelectMgr/SelectMgr_BVHThreadPool.hxx +++ b/src/Visualization/TKV3d/SelectMgr/SelectMgr_BVHThreadPool.hxx @@ -16,11 +16,12 @@ #include #include -#include #include #include #include +#include + //! Class defining a thread pool for building BVH for the list of Select3D_SensitiveEntity within //! background thread(s). class SelectMgr_BVHThreadPool : public Standard_Transient @@ -57,7 +58,7 @@ public: } //! Returns mutex used for BVH building - Standard_Mutex& BVHMutex() { return myMutex; } + std::mutex& BVHMutex() { return myMutex; } //! Assignment operator. BVHThread& operator=(const BVHThread& theCopy) @@ -83,7 +84,7 @@ public: private: SelectMgr_BVHThreadPool* myPool; - Standard_Mutex myMutex; + std::mutex myMutex; bool myToCatchFpe; }; @@ -122,7 +123,7 @@ public: { for (Standard_Integer i = myPool->Threads().Lower(); i <= myPool->Threads().Upper(); ++i) { - myPool->Threads().ChangeValue(i).BVHMutex().Lock(); + myPool->Threads().ChangeValue(i).BVHMutex().lock(); } } } @@ -134,7 +135,7 @@ public: { for (Standard_Integer i = myPool->Threads().Lower(); i <= myPool->Threads().Upper(); ++i) { - myPool->Threads().ChangeValue(i).BVHMutex().Unlock(); + myPool->Threads().ChangeValue(i).BVHMutex().unlock(); } } } @@ -153,7 +154,7 @@ protected: NCollection_List myBVHToBuildList; //!< list of queued sensitive entities NCollection_Array1 myBVHThreads; //!< threads to build BVH Standard_Boolean myToStopBVHThread; //!< flag to stop BVH threads - Standard_Mutex myBVHListMutex; //!< mutex for interaction with myBVHToBuildList + std::mutex myBVHListMutex; //!< mutex for interaction with myBVHToBuildList Standard_Condition myWakeEvent; //!< raises when any sensitive is added to the BVH list Standard_Condition myIdleEvent; //!< raises when BVH list become empty Standard_Boolean myIsStarted; //!< indicates that threads are running diff --git a/src/Visualization/TKV3d/StdPrs/StdPrs_BRepFont.cxx b/src/Visualization/TKV3d/StdPrs/StdPrs_BRepFont.cxx index bfecb2e7d8..3d7159c8d9 100644 --- a/src/Visualization/TKV3d/StdPrs/StdPrs_BRepFont.cxx +++ b/src/Visualization/TKV3d/StdPrs/StdPrs_BRepFont.cxx @@ -256,8 +256,8 @@ bool StdPrs_BRepFont::FindAndInit(const TCollection_AsciiString& theFontName, TopoDS_Shape StdPrs_BRepFont::RenderGlyph(const Standard_Utf32Char& theChar) { - TopoDS_Shape aShape; - Standard_Mutex::Sentry aSentry(myMutex); + TopoDS_Shape aShape; + std::lock_guard aLock(myMutex); renderGlyph(theChar, aShape); return aShape; } diff --git a/src/Visualization/TKV3d/StdPrs/StdPrs_BRepFont.hxx b/src/Visualization/TKV3d/StdPrs/StdPrs_BRepFont.hxx index 8d9ed76a45..54b5794571 100644 --- a/src/Visualization/TKV3d/StdPrs/StdPrs_BRepFont.hxx +++ b/src/Visualization/TKV3d/StdPrs/StdPrs_BRepFont.hxx @@ -23,11 +23,12 @@ #include #include #include -#include #include #include #include +#include + DEFINE_STANDARD_HANDLE(StdPrs_BRepFont, Standard_Transient) //! This tool provides basic services for rendering of vectorized text glyphs as BRep shapes. @@ -169,7 +170,7 @@ public: Standard_Real Scale() const { return myScaleUnits; } //! Returns mutex. - Standard_Mutex& Mutex() { return myMutex; } + std::mutex& Mutex() { return myMutex; } public: //! Find (using Font_FontMgr) and initialize the font from the given name. @@ -206,7 +207,7 @@ private: protected: //! @name Protected fields Handle(Font_FTFont) myFTFont; //!< wrapper over FreeType font NCollection_DataMap myCache; //!< glyphs cache - Standard_Mutex myMutex; //!< lock for thread-safety + std::mutex myMutex; //!< lock for thread-safety Handle(Geom_Surface) mySurface; //!< surface to place glyphs on to Standard_Real myPrecision; //!< algorithm precision Standard_Real myScaleUnits; //!< scale font rendering units into model units diff --git a/src/Visualization/TKV3d/StdPrs/StdPrs_BRepTextBuilder.cxx b/src/Visualization/TKV3d/StdPrs/StdPrs_BRepTextBuilder.cxx index aa06521fbe..4613e47117 100644 --- a/src/Visualization/TKV3d/StdPrs/StdPrs_BRepTextBuilder.cxx +++ b/src/Visualization/TKV3d/StdPrs/StdPrs_BRepTextBuilder.cxx @@ -23,11 +23,10 @@ TopoDS_Shape StdPrs_BRepTextBuilder::Perform(StdPrs_BRepFont& t const Handle(Font_TextFormatter)& theFormatter, const gp_Ax3& thePenLoc) { - gp_Trsf aTrsf; - gp_XYZ aPen; - TopoDS_Shape aGlyphShape; - TopoDS_Compound aResult; - Standard_Mutex::Sentry aSentry(theFont.Mutex()); + gp_Trsf aTrsf; + gp_XYZ aPen; + TopoDS_Shape aGlyphShape; + TopoDS_Compound aResult; myBuilder.MakeCompound(aResult); diff --git a/src/Visualization/TKV3d/StdPrs/StdPrs_WFShape.cxx b/src/Visualization/TKV3d/StdPrs/StdPrs_WFShape.cxx index deeca8f6d5..6e6c282c92 100644 --- a/src/Visualization/TKV3d/StdPrs/StdPrs_WFShape.cxx +++ b/src/Visualization/TKV3d/StdPrs/StdPrs_WFShape.cxx @@ -37,7 +37,8 @@ #include #include #include -#include + +#include //! Functor for executing StdPrs_Isolines in parallel threads. class StdPrs_WFShape_IsoFunctor @@ -63,7 +64,7 @@ public: const TopoDS_Face& aFace = myFaces[theIndex]; StdPrs_Isolines::Add(aFace, myDrawer, myShapeDeflection, aPolylinesU, aPolylinesV); { - Standard_Mutex::Sentry aLock(myMutex); + std::lock_guard aLock(myMutex); myPolylinesU.Append(aPolylinesU); myPolylinesV.Append(aPolylinesV); } @@ -77,7 +78,7 @@ private: Prs3d_NListOfSequenceOfPnt& myPolylinesV; const std::vector& myFaces; const Handle(Prs3d_Drawer)& myDrawer; - mutable Standard_Mutex myMutex; + mutable std::mutex myMutex; const Standard_Real myShapeDeflection; };