12 #ifdef PXR_BASE_TF_INSTANTIATE_SINGLETON_H
13 #error This file should only be included once in any given source (.cpp) file.
16 #define PXR_BASE_TF_INSTANTIATE_SINGLETON_H
25 #include "pxr/base/tf/mallocTag.h"
48 #ifdef PXR_PYTHON_SUPPORT_ENABLED
49 std::unique_ptr<class TfPyLock> _pyLock;
50 #endif // PXR_PYTHON_SUPPORT_ENABLED
65 std::unique_ptr<Tf_SingletonInitState> initState(
67 std::this_thread::get_id(),
static_cast<void *
>(&instance)
70 if (_instance.load() || _initState.exchange(initState.get()) !=
nullptr) {
72 "GetInstance() or another SetInstanceConstructed() "
82 static std::atomic<bool> isInitializing;
84 TfAutoMallocTag tag(
"Tf",
"TfSingleton::_CreateOrWaitForInstance",
85 "Create Singleton " + ArchGetDemangled<T>());
91 if (initState->initThreadId == std::this_thread::get_id()) {
93 return static_cast<T *
>(initState->initInstance);
105 if (isInitializing.exchange(
true) ==
false) {
116 delete _initState.exchange(
nullptr);
119 T *curInst =
nullptr;
122 curInst =
static_cast<T *
>(initState->initInstance);
124 if (curInst && (curInst != newInst)) {
127 TF_AXIOM(instance.exchange(newInst) ==
nullptr);
129 isInitializing =
false;
137 return instance.load();
140 template <
typename T>
146 T *instance = _instance.load();
147 if (instance && _instance.compare_exchange_strong(instance,
nullptr)) {
149 delete _initState.exchange(
nullptr);
160 #define TF_INSTANTIATE_SINGLETON(T) \
161 template class PXR_NS_GLOBAL::TfSingleton<T>
#define PXR_NAMESPACE_OPEN_SCOPE
const std::thread::id initThreadId
static void SetInstanceConstructed(T &instance)
#define PXR_NAMESPACE_CLOSE_SCOPE
static void DeleteInstance()
TF_API Tf_SingletonPyGILDropper()
TF_API ~Tf_SingletonPyGILDropper()