From 3977f4b4976bc30c9d3c8d6d388fd3c5e042e75a Mon Sep 17 00:00:00 2001 From: Markus FRANK <Markus.Frank@cern.ch> Date: Fri, 19 Mar 2021 10:30:55 +0100 Subject: [PATCH] Protect Detector and geometry for parallel/multithreaded construction --- DDCore/src/DetectorImp.cpp | 31 ++++++++++++++++++++++++-- DDCore/src/plugins/StandardPlugins.cpp | 5 +++-- UtilityApps/src/display.cpp | 8 ++++--- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/DDCore/src/DetectorImp.cpp b/DDCore/src/DetectorImp.cpp index b744bd69c..74e12ba12 100644 --- a/DDCore/src/DetectorImp.cpp +++ b/DDCore/src/DetectorImp.cpp @@ -100,11 +100,34 @@ namespace { return 0; } }; - static Instances& detector_instances() { + + Instances& detector_instances() { static Instances s_inst; return s_inst; } + pair<mutex, map<DetectorImp*, TGeoManager*> >& detector_lock() { + static pair<mutex, map<DetectorImp*, TGeoManager*> > s_inst; + return s_inst; + } + + void lock_detector(DetectorImp* imp, TGeoManager* mgr) { + auto& lock = detector_lock(); + lock.first.lock(); + lock.second[imp] = mgr; + } + TGeoManager* unlock_detector(DetectorImp* imp) { + TGeoManager* mgr = nullptr; + auto& lock = detector_lock(); + auto i = lock.second.find(imp); + if ( i != lock.second.end() ) { + mgr = (*i).second; + lock.second.erase(i); + } + lock.first.unlock(); + return mgr; + } + void description_unexpected() { try { throw; @@ -198,8 +221,9 @@ DetectorImp::DetectorImp(const string& name) SetName(name.c_str()); SetTitle("DD4hep detector description object"); set_terminate( description_unexpected ); + lock_detector( this, gGeoManager ); + gGeoManager = nullptr; InstanceCount::increment(this); - //if ( gGeoManager ) delete gGeoManager; m_manager = new TGeoManager(name.c_str(), "Detector Geometry"); { m_manager->AddNavigator(); @@ -234,6 +258,7 @@ DetectorImp::DetectorImp(const string& name) /// Standard destructor DetectorImp::~DetectorImp() { + lock_detector( this, gGeoManager ); if ( m_manager ) { lock_guard<recursive_mutex> lock(detector_instances().lock); if ( m_manager == gGeoManager ) gGeoManager = 0; @@ -250,6 +275,7 @@ DetectorImp::~DetectorImp() { m_extensions.clear(); m_detectorTypes.clear(); InstanceCount::decrement(this); + gGeoManager = unlock_detector(this); } /// ROOT I/O call @@ -719,6 +745,7 @@ void DetectorImp::endDocument(bool close_geometry) { patcher.patchShapes(); mapDetectorTypes(); m_state = READY; + gGeoManager = unlock_detector(this); } /// Initialize the geometry and set the bounding box of the world volume diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp index 3b22c1b48..4eb52cb0f 100644 --- a/DDCore/src/plugins/StandardPlugins.cpp +++ b/DDCore/src/plugins/StandardPlugins.cpp @@ -135,12 +135,13 @@ static long display(Detector& description, int argc, char** argv) { detector = argv[++i]; else { cout << - "Usage: -plugin <name> -arg [-arg] \n" + "Usage: -plugin DD4hep_GeometryDisplay -arg [-arg] \n\n" " -detector <string> Top level DetElement path. Default: '/world' \n" " -option <string> ROOT Draw option. Default: 'ogl' \n" " -level <number> Visualization level [TGeoManager::SetVisLevel] Default: 4 \n" " -visopt <number> Visualization option [TGeoManager::SetVisOption] Default: 1 \n" - "\tArguments given: " << arguments(argc,argv) << endl << flush; + " -help Print this help output \n" + " Arguments given: " << arguments(argc,argv) << endl << flush; ::exit(EINVAL); } } diff --git a/UtilityApps/src/display.cpp b/UtilityApps/src/display.cpp index f4fa3643a..53c2f7a05 100644 --- a/UtilityApps/src/display.cpp +++ b/UtilityApps/src/display.cpp @@ -18,11 +18,12 @@ int main(int argc,char** argv) { std::vector<const char*> av; std::string level, visopt, opt, detector; - bool dry = false; + bool dry = false, help = false; for(int i=0; i<argc; ++i) { if ( i==1 && argv[i][0] != '-' ) av.emplace_back("-input"); - if ( strncmp(argv[i],"-load-only",4) == 0 ) dry = true, av.emplace_back(argv[i]); - else if ( strncmp(argv[i],"-dry-run",4) == 0 ) dry = true, av.emplace_back(argv[i]); + if ( strncmp(argv[i],"-load-only",4) == 0 ) dry = true, av.emplace_back(argv[i]); + else if ( strncmp(argv[i],"-dry-run",4) == 0 ) dry = true, av.emplace_back(argv[i]); + else if ( strncmp(argv[i],"-help",4) == 0 ) help = true, av.emplace_back(argv[i]); else if ( strncmp(argv[i],"-visopt",4) == 0 ) visopt = argv[++i]; else if ( strncmp(argv[i],"-level", 4) == 0 ) level = argv[++i]; else if ( strncmp(argv[i],"-option",4) == 0 ) opt = argv[++i]; @@ -33,6 +34,7 @@ int main(int argc,char** argv) { av.emplace_back("-interactive"); av.emplace_back("-plugin"); av.emplace_back("DD4hep_GeometryDisplay"); + if ( help ) av.emplace_back("-help"); if ( !opt.empty() ) av.emplace_back("-opt"), av.emplace_back(opt.c_str()); if ( !level.empty() ) av.emplace_back("-level"), av.emplace_back(level.c_str()); if ( !visopt.empty() ) av.emplace_back("-visopt"), av.emplace_back(visopt.c_str()); -- GitLab