I385a05a3ca01258e44fe3b37ef77e4aaff547b26 broke Singleton in the
same way that 544e3e3606 had already
fixed once. Fix it again, the next CL will add tests.
This affected cases where two libraries referenced the same singleton,
the one that was supposed to define the singleton was already loaded,
and then the second library was dlopen'd.
Bug: 35674422
Test: out/host/linux-x86/nativetest64/libutils_tests/libutils_tests
from later CL
Change-Id: I87c64f95ed294a887e67a6c11be3072299789f01
93 lines
2.8 KiB
C++
93 lines
2.8 KiB
C++
/*
|
|
* Copyright (C) 2007 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* 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 ANDROID_UTILS_SINGLETON_H
|
|
#define ANDROID_UTILS_SINGLETON_H
|
|
|
|
#include <stdint.h>
|
|
#include <sys/types.h>
|
|
#include <utils/Mutex.h>
|
|
#include <utils/threads.h>
|
|
#include <cutils/compiler.h>
|
|
|
|
namespace android {
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// Singleton<TYPE> may be used in multiple libraries, only one of which should
|
|
// define the static member variables using ANDROID_SINGLETON_STATIC_INSTANCE.
|
|
// Turn off -Wundefined-var-template so other users don't get:
|
|
// instantiation of variable 'android::Singleton<TYPE>::sLock' required here,
|
|
// but no definition is available
|
|
#if defined(__clang__)
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wundefined-var-template"
|
|
#endif
|
|
|
|
template <typename TYPE>
|
|
class ANDROID_API Singleton
|
|
{
|
|
public:
|
|
static TYPE& getInstance() {
|
|
Mutex::Autolock _l(sLock);
|
|
TYPE* instance = sInstance;
|
|
if (instance == 0) {
|
|
instance = new TYPE();
|
|
sInstance = instance;
|
|
}
|
|
return *instance;
|
|
}
|
|
|
|
static bool hasInstance() {
|
|
Mutex::Autolock _l(sLock);
|
|
return sInstance != 0;
|
|
}
|
|
|
|
protected:
|
|
~Singleton() { }
|
|
Singleton() { }
|
|
|
|
private:
|
|
Singleton(const Singleton&);
|
|
Singleton& operator = (const Singleton&);
|
|
static Mutex sLock;
|
|
static TYPE* sInstance;
|
|
};
|
|
|
|
#if defined(__clang__)
|
|
#pragma clang diagnostic pop
|
|
#endif
|
|
|
|
/*
|
|
* use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file
|
|
* (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,
|
|
* and avoid to have a copy of them in each compilation units Singleton<TYPE>
|
|
* is used.
|
|
* NOTE: we use a version of Mutex ctor that takes a parameter, because
|
|
* for some unknown reason using the default ctor doesn't emit the variable!
|
|
*/
|
|
|
|
#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \
|
|
template<> ::android::Mutex \
|
|
(::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE); \
|
|
template<> TYPE* ::android::Singleton< TYPE >::sInstance(0); \
|
|
template class ::android::Singleton< TYPE >;
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
}; // namespace android
|
|
|
|
#endif // ANDROID_UTILS_SINGLETON_H
|
|
|