Branch data Line data Source code
1 : : /* 2 : : ** Copyright (C) 2012 Fargier Sylvain <fargier.sylvain@free.fr> 3 : : ** 4 : : ** This software is provided 'as-is', without any express or implied 5 : : ** warranty. In no event will the authors be held liable for any damages 6 : : ** arising from the use of this software. 7 : : ** 8 : : ** Permission is granted to anyone to use this software for any purpose, 9 : : ** including commercial applications, and to alter it and redistribute it 10 : : ** freely, subject to the following restrictions: 11 : : ** 12 : : ** 1. The origin of this software must not be misrepresented; you must not 13 : : ** claim that you wrote the original software. If you use this software 14 : : ** in a product, an acknowledgment in the product documentation would be 15 : : ** appreciated but is not required. 16 : : ** 2. Altered source versions must be plainly marked as such, and must not be 17 : : ** misrepresented as being the original software. 18 : : ** 3. This notice may not be removed or altered from any source distribution. 19 : : ** 20 : : ** Singleton.hxx 21 : : ** 22 : : ** Created on: Nov 12, 2012 23 : : ** Original Author: Sylvain Fargier <fargier.sylvain@free.fr> 24 : : ** 25 : : */ 26 : : 27 : : /** 28 : : * @brief Template code Singleton class 29 : : * @details this class is not automatically included since the template must be 30 : : * instantiated with caution on windows like systems, see : 31 : : * http://www.codesynthesis.com/~boris/blog/2010/01/18/dll-export-cxx-templates/ 32 : : */ 33 : : #ifndef __SINGLETON_HXX__ 34 : : #define __SINGLETON_HXX__ 35 : : 36 : : #include "Singleton.hpp" 37 : : #include <logger/Logger.hpp> 38 : : 39 : : namespace ccut { 40 : : 41 : : template<class C, SingletonType T> 42 : 6 : C &Singleton<C, T>::instance() 43 : : { 44 : 6 : if (!m_instance) 45 : : { 46 : 2 : SingletonMutex lock; 47 : 2 : if (!m_instance) 48 : 2 : m_instance = new C(); 49 : 2 : } 50 : 6 : return *m_instance; 51 : : } 52 : : 53 : : template<class C, SingletonType T> 54 : 4 : void Singleton<C, T>::destroy() 55 : : { 56 : 4 : SingletonMutex lock; 57 : 4 : if (m_instance) 58 : : { 59 : 2 : delete m_instance; 60 : 2 : m_instance = NULL; 61 : : } 62 : 4 : } 63 : : 64 : : template<class C, SingletonType T> 65 : : C *Singleton<C, T>::m_instance = 0; 66 : : 67 : : template<class C> 68 : 3 : std::shared_ptr<C> Singleton<C, SingletonType::automatic>::instance() 69 : : { 70 : 3 : std::shared_ptr<C> ret = m_instance.lock(); 71 : 3 : if (!ret) 72 : : { 73 : 2 : SingletonMutex lock; 74 : 2 : ret = m_instance.lock(); 75 : 2 : if (!ret) 76 : : { 77 : 2 : ret.reset(new C()); 78 : 2 : m_instance = ret; 79 : : } 80 : 2 : } 81 : 3 : return ret; 82 : 0 : } 83 : : 84 : : template<class C> 85 : : std::weak_ptr<C> Singleton<C, SingletonType::automatic>::m_instance; 86 : : 87 : : template<class C> 88 : 5 : std::shared_ptr<C> Singleton<C, SingletonType::shared>::instance() 89 : : { 90 : 5 : std::shared_ptr<C> ret = m_instance; 91 : 5 : if (!ret) 92 : : { 93 : 2 : SingletonMutex lock; 94 : 2 : if (!m_instance) 95 : 2 : m_instance.reset(new C()); 96 : 2 : ret = m_instance; 97 : 2 : } 98 : 5 : return ret; 99 : 0 : } 100 : : 101 : : template<class C> 102 : 2 : void Singleton<C, SingletonType::shared>::destroy() 103 : : { 104 : 2 : SingletonMutex lock; 105 : 2 : if (m_instance.use_count() > 1) 106 : 1 : logger::warning("ccut::singleton") << "destroying in-use singleton"; 107 : 2 : m_instance.reset(); 108 : 2 : } 109 : : 110 : : template<class C> 111 : : std::shared_ptr<C> Singleton<C, SingletonType::shared>::m_instance; 112 : : 113 : : } // namespace ccut 114 : : 115 : : #endif // __SINGLETON_HXX__