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 : 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 7204103 : Singleton & getSingleton() { 47 7204103 : static Singleton singleton; 48 7204103 : return singleton; 49 : } 50 : 51 : } 52 : 53 59 : Register::RegistrationLock::RegistrationLock(const std::string & fullPath): 54 59 : active(true) { 55 59 : pushDLRegistration(fullPath); 56 59 : } 57 : 58 59 : Register::RegistrationLock::~RegistrationLock() noexcept { 59 59 : if(active) { 60 59 : popDLRegistration(); 61 : } 62 59 : } 63 : 64 0 : Register::RegistrationLock::RegistrationLock(RegistrationLock&& other) noexcept: 65 0 : active(other.active) { 66 0 : other.active=false; 67 0 : } 68 : 69 59 : Register::RegistrationLock Register::registrationLock(const std::string & fullPath) { 70 59 : return RegistrationLock(fullPath); 71 : } 72 : 73 59 : void Register::pushDLRegistration(const std::string & fullPath) { 74 59 : auto & singleton=getSingleton(); 75 59 : singleton.registeringMutex.lock(); 76 59 : singleton.fullPath=fullPath; 77 59 : 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 59 : singleton.registeringCounter++; 82 59 : } 83 : 84 59 : void Register::popDLRegistration() noexcept { 85 59 : auto & singleton=getSingleton(); 86 177 : for(auto & reg : singleton.registers) { 87 118 : reg->clearStaged(); 88 : } 89 59 : singleton.registeringCounter--; 90 : singleton.registeringMutex.unlock(); 91 59 : } 92 : 93 59 : void Register::completeAllRegistrations(void* image) { 94 59 : auto & singleton=getSingleton(); 95 177 : for(auto & reg : singleton.registers) { 96 118 : reg->completeRegistration(image); 97 : } 98 59 : } 99 : 100 300 : std::string Register::imageToString(void* image) { 101 300 : std::stringstream ss; 102 : ss << image; 103 300 : return ss.str(); 104 300 : } 105 : 106 3587321 : bool Register::isDLRegistering() noexcept { 107 3587321 : auto & singleton=getSingleton(); 108 3587321 : return singleton.registeringCounter>0; 109 : } 110 : 111 3587321 : const std::string Register::getRegisteringFullPath() noexcept { 112 3587321 : auto & singleton=getSingleton(); 113 3587321 : return singleton.fullPath; 114 : } 115 : 116 14642 : Register::Register() { 117 14642 : auto & singleton=getSingleton(); 118 : // this is to protect insertion 119 14642 : std::unique_lock lock(singleton.registeringMutex); 120 14642 : singleton.registers.push_back(this); 121 14642 : } 122 : 123 14642 : Register::~Register() noexcept { 124 14642 : auto & singleton=getSingleton(); 125 : // this is to protect removal 126 14642 : std::unique_lock lock(singleton.registeringMutex); 127 14642 : auto it=std::find(singleton.registers.begin(),singleton.registers.end(),this); 128 14642 : if(it!=singleton.registers.end()) { 129 14642 : singleton.registers.erase(it); 130 : } 131 14642 : } 132 : 133 49 : std::vector<std::string> Register::getKeysWithDLHandle(void* image) const { 134 49 : std::vector<std::string> res; 135 49 : const auto prefix=imageToString(image)+":"; 136 23203 : for(auto & k : getKeys()) { 137 23154 : if(Tools::startWith(k,prefix)) { 138 49 : if(!std::getenv("PLUMED_LOAD_ACTION_DEBUG")) { 139 98 : k=k.substr(prefix.length()); 140 : } 141 49 : res.push_back(k); 142 : } 143 49 : } 144 49 : return res; 145 0 : } 146 : 147 953 : std::ostream & operator<<(std::ostream &log,const Register ®) { 148 953 : std::vector<std::string> s(reg.getKeys()); 149 234664 : for(unsigned i=0; i<s.size(); i++) { 150 467422 : log<<" "<<s[i]<<"\n"; 151 : } 152 953 : return log; 153 953 : } 154 : 155 : 156 : }