123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- /**
- * Tencent is pleased to support the open source community by making Tars available.
- *
- * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
- *
- * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * https://opensource.org/licenses/BSD-3-Clause
- *
- * Unless required by applicable law or agreed to in writing, software distributed
- * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
- #ifndef __TC_SINGLETON_H__
- #define __TC_SINGLETON_H__
- #include "util/tc_monitor.h"
- #include <cassert>
- #include <cstdlib>
- namespace tars
- {
- /////////////////////////////////////////////////
- /**
- * @file tc_singleton.h
- * @brief 单件类 .
- *
- * 单件实现类
- *
- * 没有实现对单件生命周期的管理,使用示例代码如下:
- *
- * class A : public TC_Singleton<A, CreateStatic, DefaultLifetime>
- *
- * {
- *
- * public:
- *
- * A(){cout << "A" << endl;}
- *
- * ~A()
- *
- * {
- *
- * cout << "~A" << endl;
- *
- *
- * }
- *
- * void test(){cout << "test A" << endl;}
- *
- * };
- * 对象的创建方式由CreatePolicy指定, 有如下方式:
- *
- * CreateUsingNew: 在堆中采用new创建
- *
- * CreateStatic`: 在栈中采用static创建
- *
- * 对象生命周期管理由LifetimePolicy指定, 有如下方式:
- *
- * DefaultLifetime:缺省声明周期管理
- *
- *如果单件对象已经析够, 但是还有调用, 会触发异常
- *
- * PhoneixLifetime:不死生命周期
- *
- * 如果单件对象已经析够, 但是还有调用, 会再创建一个
- *
- * NoDestroyLifetime:不析够
- *
- * 对象创建后不会调用析够函数析够, 通常采用实例中的方式就可以了
- *
- */
- /////////////////////////////////////////////////
- /**
- * @brief 定义CreatePolicy:定义对象创建策略
- */
- template<typename T>
- class CreateUsingNew
- {
- public:
- /**
- * @brief 创建.
- *
- * @return T*
- */
- static T* create()
- {
- return new T;
- }
- /**
- * @brief 释放.
- *
- * @param t
- */
- static void destroy(T *t)
- {
- delete t;
- }
- };
- template<typename T>
- class CreateUsingNew1
- {
- public:
- /**
- * @brief 创建.
- *
- * @return T*
- */
- static T* create()
- {
- return new T;
- }
- /**
- * @brief 释放.
- *
- * @param t
- */
- static void destroy(T *t)
- {
- delete t;
- }
- };
- template<typename T>
- class CreateStatic
- {
- public:
- /**
- * @brief 最大的空间
- */
- union MaxAlign
- {
- char t_[sizeof(T)];
- long double longDouble_;
- };
- /**
- * @brief 创建.
- *
- * @return T*
- */
- static T* create()
- {
- static MaxAlign t;
- return new(&t) T;
- }
- /**
- * @brief 释放.
- *
- * @param t
- */
- static void destroy(T *t)
- {
- t->~T();
- }
- };
- template<typename T>
- class CreateRealStatic
- {
- public:
- /**
- * @brief 创建.
- *
- * @return T*
- */
- static T* create()
- {
- static T t;
- return &t;
- }
- /**
- * @brief 释放.
- *
- * @param t
- */
- static void destroy(T *t)
- {
- }
- };
- ////////////////////////////////////////////////////////////////
- /**
- * @brief 定义LifetimePolicy:定义对象的声明周期管理
- * 进程退出时销毁对象
- */
- template<typename T>
- class DefaultLifetime
- {
- public:
- static void deadReference()
- {
- throw std::logic_error("singleton object has dead.");
- }
- static void scheduleDestruction(T*, void (*pFun)())
- {
- std::atexit(pFun);
- }
- };
- /**
- * @brief,
- * 对象被销毁后可以重生(比如log,全局任何时候都需要)
- *
- * @author jarod (7/29/2015)
- */
- template<typename T>
- class PhoneixLifetime
- {
- public:
- static void deadReference()
- {
- _bDestroyedOnce = true;
- }
- static void scheduleDestruction(T*, void (*pFun)())
- {
- if(!_bDestroyedOnce)
- std::atexit(pFun);
- }
- private:
- static bool _bDestroyedOnce;
- };
- template <class T>
- bool PhoneixLifetime<T>::_bDestroyedOnce = false;
- /**
- * @brief 不做对象销毁
- *
- * @author jarod (7/29/2015)
- */
- template <typename T>
- struct NoDestroyLifetime
- {
- static void scheduleDestruction(T*, void (*)())
- {
- }
- static void deadReference()
- {
- }
- };
- //////////////////////////////////////////////////////////////////////
- // Singleton
- template
- <
- typename T,
- template<typename> class CreatePolicy = CreateUsingNew,
- template<typename> class LifetimePolicy = DefaultLifetime
- >
- class TC_Singleton
- {
- public:
- typedef T instance_type;
- typedef volatile T volatile_type;
-
- typedef CreatePolicy<T> TCreatePolicy;
- /**
- * @brief 获取实例
- *
- * @return T*
- */
- static T *getInstance()
- {
- static std::mutex __mutex_singleton;
- auto sin= __pInstance.load();
- if ( !sin ){
- std::lock_guard<std::mutex> myLock(__mutex_singleton);
- sin= __pInstance.load();
- if( !sin ){
- if(__destroyed)
- {
- LifetimePolicy<T>::deadReference();
- __destroyed = false;
- }
- sin = CreatePolicy<T>::create();
- __pInstance.store(sin);
- LifetimePolicy<T>::scheduleDestruction(__pInstance, &destroySingleton);
- }
- }
- return sin;
- }
- virtual ~TC_Singleton(){};
- protected:
- static void destroySingleton()
- {
- assert(!__destroyed);
- CreatePolicy<T>::destroy((T*)__pInstance);
- __pInstance = NULL;
- __destroyed = true;
- }
- protected:
- static atomic<T*> __pInstance;
- static bool __destroyed;
- protected:
- TC_Singleton() = default;
- TC_Singleton (const TC_Singleton &) = default;
- TC_Singleton &operator=(const TC_Singleton &) = default;
- };
- template <class T, template<class> class CreatePolicy, template<class> class LifetimePolicy>
- bool TC_Singleton<T, CreatePolicy, LifetimePolicy>::__destroyed = false;
- template <class T, template<class> class CreatePolicy, template<class> class LifetimePolicy>
- atomic<T*> TC_Singleton<T, CreatePolicy, LifetimePolicy>::__pInstance = {nullptr};
- }
- #endif
|