Line data Source code
1 : /* 2 : * Copyright (C) 2004-2025 Savoir-faire Linux Inc. 3 : * 4 : * This program is free software: you can redistribute it and/or modify 5 : * it under the terms of the GNU General Public License as published by 6 : * the Free Software Foundation, either version 3 of the License, or 7 : * (at your option) any later version. 8 : * 9 : * This program is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 : * GNU General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU General Public License 15 : * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 : */ 17 : 18 : #pragma once 19 : 20 : #include <memory> 21 : #include <mutex> 22 : 23 : namespace jami { 24 : 25 : /** 26 : * Return a shared pointer on an auto-generated global instance of class T. 27 : * This instance is created only at usage and destroyed when not, 28 : * as we keep only a weak reference on it. 29 : * But when created it's always the same object until all holders release 30 : * their sharing. 31 : * An optional MaxRespawn positive integer can be given to limit the number 32 : * of time the object can be created (i.e. different instance). 33 : * Any negative values (default) block this effect (unlimited respawn). 34 : * This function is thread-safe. 35 : */ 36 : template<class T, signed MaxRespawn = -1> 37 : std::shared_ptr<T> 38 857 : getGlobalInstance() 39 : { 40 : static std::recursive_mutex mutex; // recursive as instance calls recursively 41 857 : static std::weak_ptr<T> wlink; 42 : 43 857 : std::unique_lock lock(mutex); 44 : 45 857 : if (wlink.expired()) { 46 : static signed counter {MaxRespawn}; 47 269 : if (not counter) 48 0 : return nullptr; 49 269 : auto link = std::make_shared<T>(); 50 269 : wlink = link; 51 269 : if (counter > 0) 52 0 : --counter; 53 269 : return link; 54 269 : } 55 : 56 588 : return wlink.lock(); 57 857 : } 58 : 59 : } // namespace jami