Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2011-2023 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed is free software: you can redistribute it and/or modify 10 : it under the terms of the GNU Lesser General Public License as published by 11 : the Free Software Foundation, either version 3 of the License, or 12 : (at your option) any later version. 13 : 14 : plumed is distributed in the hope that it will be useful, 15 : but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : GNU Lesser General Public License for more details. 18 : 19 : You should have received a copy of the GNU Lesser General Public License 20 : along with plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #include "RegisterBase.h" 23 : 24 : #include <mutex> 25 : #include "tools/Tools.h" 26 : 27 : namespace PLMD { 28 : 29 : namespace { 30 5883 : class Singleton { 31 : public: 32 : /// Mutex to avoid simultaneous registrations from multiple threads 33 : std::mutex registeringMutex; 34 : 35 : /// Count simultaneous registrations 36 : /// This is here if in the future we want to expand to recursive registrations 37 : unsigned registeringCounter=0; 38 : 39 : /// Take care of all exisiting registers 40 : std::vector<Register*> registers; 41 : 42 : /// Full path of the registering library 43 : std::string fullPath; 44 : }; 45 : 46 5412549 : Singleton & getSingleton() { 47 5412549 : static Singleton singleton; 48 5412549 : return singleton; 49 : } 50 : 51 : } 52 : 53 51 : Register::RegistrationLock::RegistrationLock(const std::string & fullPath): 54 51 : active(true) { 55 51 : pushDLRegistration(fullPath); 56 51 : } 57 : 58 51 : Register::RegistrationLock::~RegistrationLock() noexcept { 59 51 : if(active) { 60 51 : popDLRegistration(); 61 : } 62 51 : } 63 : 64 0 : Register::RegistrationLock::RegistrationLock(RegistrationLock&& other) noexcept: 65 0 : active(other.active) { 66 0 : other.active=false; 67 0 : } 68 : 69 51 : Register::RegistrationLock Register::registrationLock(const std::string & fullPath) { 70 51 : return RegistrationLock(fullPath); 71 : } 72 : 73 51 : void Register::pushDLRegistration(const std::string & fullPath) { 74 51 : auto & singleton=getSingleton(); 75 51 : singleton.registeringMutex.lock(); 76 51 : singleton.fullPath=fullPath; 77 51 : if(singleton.registeringCounter>0) { 78 : singleton.registeringMutex.unlock(); 79 0 : plumed_error()<<"recursive registrations are technically possible but disabled at this stage "<<singleton.registeringCounter; 80 : } 81 51 : singleton.registeringCounter++; 82 51 : } 83 : 84 51 : void Register::popDLRegistration() noexcept { 85 51 : auto & singleton=getSingleton(); 86 153 : for(auto & reg : singleton.registers) { 87 102 : reg->clearStaged(); 88 : } 89 51 : singleton.registeringCounter--; 90 : singleton.registeringMutex.unlock(); 91 51 : } 92 : 93 51 : void Register::completeAllRegistrations(void* image) { 94 51 : auto & singleton=getSingleton(); 95 153 : for(auto & reg : singleton.registers) { 96 102 : reg->completeRegistration(image); 97 : } 98 51 : } 99 : 100 241 : std::string Register::imageToString(void* image) { 101 241 : std::stringstream ss; 102 : ss << image; 103 241 : return ss.str(); 104 241 : } 105 : 106 2694432 : bool Register::isDLRegistering() noexcept { 107 2694432 : auto & singleton=getSingleton(); 108 2694432 : return singleton.registeringCounter>0; 109 : } 110 : 111 2694432 : const std::string Register::getRegisteringFullPath() noexcept { 112 2694432 : auto & singleton=getSingleton(); 113 2694432 : return singleton.fullPath; 114 : } 115 : 116 11766 : Register::Register() { 117 11766 : auto & singleton=getSingleton(); 118 : // this is to protect insertion 119 11766 : std::unique_lock lock(singleton.registeringMutex); 120 11766 : singleton.registers.push_back(this); 121 11766 : } 122 : 123 11766 : Register::~Register() noexcept { 124 11766 : auto & singleton=getSingleton(); 125 : // this is to protect removal 126 11766 : std::unique_lock lock(singleton.registeringMutex); 127 11766 : auto it=std::find(singleton.registers.begin(),singleton.registers.end(),this); 128 11766 : if(it!=singleton.registers.end()) { 129 11766 : singleton.registers.erase(it); 130 : } 131 11766 : } 132 : 133 41 : std::vector<std::string> Register::getKeysWithDLHandle(void* image) const { 134 : std::vector<std::string> res; 135 41 : const auto prefix=imageToString(image)+":"; 136 18107 : for(auto & k : getKeys()) { 137 18066 : if(Tools::startWith(k,prefix)) { 138 41 : if(!std::getenv("PLUMED_LOAD_ACTION_DEBUG")) { 139 82 : k=k.substr(prefix.length()); 140 : } 141 41 : res.push_back(k); 142 : } 143 41 : } 144 41 : return res; 145 0 : } 146 : 147 1760 : std::ostream & operator<<(std::ostream &log,const Register ®) { 148 1760 : std::vector<std::string> s(reg.getKeys()); 149 404800 : for(unsigned i=0; i<s.size(); i++) { 150 806080 : log<<" "<<s[i]<<"\n"; 151 : } 152 1760 : return log; 153 1760 : } 154 : 155 : 156 : }