1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_UTILS_SINGLETON_H 18 #define ANDROID_UTILS_SINGLETON_H 19 20 #include <stdint.h> 21 22 // some vendor code assumes they have atoi() after including this file. 23 #include <stdlib.h> 24 25 #include <sys/types.h> 26 #include <utils/Mutex.h> 27 #include <cutils/compiler.h> 28 29 namespace android { 30 // --------------------------------------------------------------------------- 31 32 // Singleton<TYPE> may be used in multiple libraries, only one of which should 33 // define the static member variables using ANDROID_SINGLETON_STATIC_INSTANCE. 34 // Turn off -Wundefined-var-template so other users don't get: 35 // instantiation of variable 'android::Singleton<TYPE>::sLock' required here, 36 // but no definition is available 37 #if defined(__clang__) 38 #pragma clang diagnostic push 39 #pragma clang diagnostic ignored "-Wundefined-var-template" 40 #endif 41 42 // DO NOT USE: Please use scoped static initialization. For instance: 43 // MyClass& getInstance() { 44 // static MyClass gInstance(...); 45 // return gInstance; 46 // } 47 template <typename TYPE> 48 class ANDROID_API Singleton 49 { 50 public: getInstance()51 static TYPE& getInstance() { 52 Mutex::Autolock _l(sLock); 53 TYPE* instance = sInstance; 54 if (instance == nullptr) { 55 instance = new TYPE(); 56 sInstance = instance; 57 } 58 return *instance; 59 } 60 hasInstance()61 static bool hasInstance() { 62 Mutex::Autolock _l(sLock); 63 return sInstance != nullptr; 64 } 65 66 protected: ~Singleton()67 ~Singleton() { } Singleton()68 Singleton() { } 69 70 private: 71 Singleton(const Singleton&); 72 Singleton& operator = (const Singleton&); 73 static Mutex sLock; 74 static TYPE* sInstance; 75 }; 76 77 #if defined(__clang__) 78 #pragma clang diagnostic pop 79 #endif 80 81 /* 82 * use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file 83 * (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes, 84 * and avoid to have a copy of them in each compilation units Singleton<TYPE> 85 * is used. 86 * NOTE: we use a version of Mutex ctor that takes a parameter, because 87 * for some unknown reason using the default ctor doesn't emit the variable! 88 */ 89 90 #define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \ 91 template<> ::android::Mutex \ 92 (::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE); \ 93 template<> TYPE* ::android::Singleton< TYPE >::sInstance(nullptr); /* NOLINT */ \ 94 template class ::android::Singleton< TYPE >; 95 96 97 // --------------------------------------------------------------------------- 98 } // namespace android 99 100 #endif // ANDROID_UTILS_SINGLETON_H 101 102