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 DFSU_SINGLETON_H 17 #define DFSU_SINGLETON_H 18 19 #include <memory> 20 #include <mutex> 21 #include <shared_mutex> 22 #include "nocopyable.h" 23 24 namespace OHOS { 25 namespace Storage { 26 namespace DistributedFile { 27 namespace Utils { 28 #define DECLARE_SINGLETON(MyClass) \ 29 public: \ 30 ~MyClass(); \ 31 MyClass(const MyClass&) = delete; \ 32 MyClass& operator=(const MyClass&) = delete; \ 33 \ 34 private: \ 35 friend DfsuSingleton<MyClass>; \ 36 MyClass(); 37 38 template<typename T> 39 class DfsuSingleton : public NoCopyable { 40 public: 41 static std::shared_ptr<T> GetInstance(); 42 43 protected: 44 /** 45 * @note We depend on the IPC manager to serialize the start and the stop procedure 46 */ 47 virtual void StartInstance() = 0; 48 49 /** 50 * @note Be very careful when freeing memory! Threads may call stop and other member functions simultaneously 51 */ 52 virtual void StopInstance() = 0; 53 }; 54 55 /** 56 * @brief 57 * 58 * @tparam T 59 * @return T& 60 * 61 * @note We use call_once to ensure the atomicity of new() and start() 62 * @note Memory leaking of T is exactly what we want. Now T will be available along the program's life-time 63 */ 64 template<typename T> GetInstance()65std::shared_ptr<T> DfsuSingleton<T>::GetInstance() 66 { 67 static std::shared_ptr<T> *dummy = nullptr; 68 static std::once_flag once; 69 std::call_once(once, []() mutable { 70 dummy = new std::shared_ptr<T>(new T()); 71 (*dummy)->StartInstance(); 72 }); 73 return *dummy; 74 } 75 } // namespace Utils 76 } // namespace DistributedFile 77 } // namespace Storage 78 } // namespace OHOS 79 #endif // DFSU_SINGLETON_H