1 /* 2 * Copyright (C) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef UTILS_BASE_SINGLETON_H 17 #define UTILS_BASE_SINGLETON_H 18 19 #include "nocopyable.h" 20 #include <mutex> 21 #include <memory> 22 23 namespace OHOS { 24 #define DECLARE_DELAYED_SINGLETON(MyClass) \ 25 do \ 26 { \ 27 public: \ 28 ~MyClass(); \ 29 private: \ 30 friend DelayedSingleton<MyClass>; \ 31 MyClass(); \ 32 } while (0) 33 34 #define DECLARE_DELAYED_REF_SINGLETON(MyClass) \ 35 do \ 36 { \ 37 private: \ 38 friend DelayedRefSingleton<MyClass>; \ 39 ~MyClass(); \ 40 MyClass(); \ 41 } while (0) 42 43 #define DECLARE_SINGLETON(MyClass) \ 44 do \ 45 { \ 46 private: \ 47 friend Singleton<MyClass>; \ 48 MyClass& operator=(const MyClass&) = delete; \ 49 MyClass(const MyClass&) = delete; \ 50 MyClass(); \ 51 ~MyClass(); \ 52 } while (0) 53 54 template<typename T> 55 class DelayedSingleton : public NoCopyable { 56 public: 57 static std::shared_ptr<T> GetInstance(); 58 static void DestroyInstance(); 59 60 private: 61 static std::shared_ptr<T> instance_; 62 static std::mutex mutex_; 63 }; 64 65 template<typename T> 66 std::shared_ptr<T> DelayedSingleton<T>::instance_ = nullptr; 67 68 template<typename T> 69 std::mutex DelayedSingleton<T>::mutex_; 70 71 template<typename T> GetInstance()72std::shared_ptr<T> DelayedSingleton<T>::GetInstance() 73 { 74 if (instance_ == nullptr) { 75 std::lock_guard<std::mutex> lock(mutex_); 76 if (instance_ == nullptr) { 77 std::shared_ptr<T> temp(new T); 78 instance_ = temp; 79 } 80 } 81 return instance_; 82 } 83 84 template<typename T> DestroyInstance()85void DelayedSingleton<T>::DestroyInstance() 86 { 87 std::lock_guard<std::mutex> lock(mutex_); 88 if (instance_ != nullptr) { 89 instance_.reset(); 90 instance_ = nullptr; 91 } 92 } 93 94 template<typename T> 95 class DelayedRefSingleton : public NoCopyable { 96 public: 97 static T& GetInstance(); 98 99 private: 100 static T* instance_; 101 static std::mutex mutex_; 102 }; 103 104 template<typename T> 105 T* DelayedRefSingleton<T>::instance_ = nullptr; 106 107 template<typename T> 108 std::mutex DelayedRefSingleton<T>::mutex_; 109 110 template<typename T> GetInstance()111T& DelayedRefSingleton<T>::GetInstance() 112 { 113 if (instance_ == nullptr) { 114 std::lock_guard<std::mutex> lock(mutex_); 115 if (instance_ == nullptr) { 116 instance_ = new T(); 117 } 118 } 119 return *instance_; 120 } 121 122 template<typename T> 123 class Singleton : public NoCopyable { 124 public: GetInstance()125 static T& GetInstance() 126 { 127 return instance_; 128 } 129 130 private: 131 static T instance_; 132 }; 133 134 template<typename T> 135 T Singleton<T>::instance_; 136 } // namespace OHOS 137 #endif 138