00001 /*MT* 00002 00003 MediaTomb - http://www.mediatomb.cc/ 00004 00005 singleton.h - this file is part of MediaTomb. 00006 00007 Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>, 00008 Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc> 00009 00010 Copyright (C) 2006-2010 Gena Batyan <bgeradz@mediatomb.cc>, 00011 Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>, 00012 Leonhard Wimmer <leo@mediatomb.cc> 00013 00014 MediaTomb is free software; you can redistribute it and/or modify 00015 it under the terms of the GNU General Public License version 2 00016 as published by the Free Software Foundation. 00017 00018 MediaTomb is distributed in the hope that it will be useful, 00019 but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 GNU General Public License for more details. 00022 00023 You should have received a copy of the GNU General Public License 00024 version 2 along with MediaTomb; if not, write to the Free Software 00025 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 00026 00027 $Id: singleton.h 2081 2010-03-23 20:18:00Z lww $ 00028 */ 00029 00031 00032 #ifndef __SINGLETON_H__ 00033 #define __SINGLETON_H__ 00034 00035 #include "sync.h" 00036 #include "zmmf/zmmf.h" 00037 00038 #define SINGLETON_CUR_MAX 15 00039 00040 template <class T> class Singleton; 00041 00042 class SingletonManager : public zmm::Object 00043 { 00044 public: 00045 static zmm::Ref<SingletonManager> getInstance(); 00046 SingletonManager(); 00047 00048 void registerSingleton(zmm::Ref<Singleton<zmm::Object> > object); 00049 virtual void shutdown(bool complete = false); 00050 00051 protected: 00052 static zmm::Ref<SingletonManager> instance; 00053 static zmm::Ref<Mutex> mutex; 00054 00055 zmm::Ref<zmm::ObjectStack<Singleton<zmm::Object> > > singletonStack; 00056 }; 00057 00058 template <class T> 00059 class Singleton : public zmm::Object 00060 { 00061 public: 00062 static zmm::Ref<T> getInstance() 00063 { 00064 if (! singletonActive) 00065 throw _ServerShutdownException(_("singleton is currently inactive!")); 00066 if (instance == nil) 00067 { 00068 AUTOLOCK(mutex); 00069 if (! singletonActive) 00070 throw _ServerShutdownException(_("singleton is currently inactive!")); 00071 if (instance == nil) // check again, because there is a very small chance 00072 // that 2 threads tried to lock() concurrently 00073 { 00074 zmm::Ref<T> tmpInstance = zmm::Ref<T>(new T()); 00075 tmpInstance->registerSingleton(); 00076 tmpInstance->init(); 00077 instance = tmpInstance; 00078 } 00079 } 00080 return instance; 00081 } 00082 00083 protected: 00084 00085 virtual ~Singleton() { } 00086 00087 virtual void init() { } 00088 virtual void shutdown() { } 00089 00090 static zmm::Ref<Mutex> mutex; 00091 static zmm::Ref<T> instance; 00092 static bool singletonActive; 00093 00094 virtual void registerSingleton() 00095 { 00096 SingletonManager::getInstance()->registerSingleton(zmm::Ref<Singleton<Object> >((Singleton<Object> *)this)); 00097 } 00098 00099 private: 00100 00101 virtual void inactivateSingleton() 00102 { 00103 //log_debug("%d %d\n", singletonActive, instance.getPtr()); 00104 singletonActive = false; 00105 instance = nil; 00106 } 00107 virtual void reactivateSingleton() { singletonActive = true; } 00108 00109 friend class SingletonManager; 00110 }; 00111 00112 #define SINGLETON_MUTEX(klass, recursive) template <> zmm::Ref<Mutex> Singleton<klass>::mutex = zmm::Ref<Mutex>(new Mutex(recursive)) 00113 //template <class T> zmm::Ref<Mutex> Singleton<T>::mutex = zmm::Ref<Mutex>(new Mutex()); 00114 template <class T> zmm::Ref<T> Singleton<T>::instance = nil; 00115 template <class T> bool Singleton<T>::singletonActive = true; 00116 00117 #endif // __SINGLETON_H__
1.6.1