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
31PXR_NAMESPACE_OPEN_SCOPE
33struct Tf_SingletonInitState
35 const std::thread::id initThreadId;
36 void *
const initInstance;
41struct Tf_SingletonPyGILDropper
44 Tf_SingletonPyGILDropper();
46 ~Tf_SingletonPyGILDropper();
48#ifdef PXR_PYTHON_SUPPORT_ENABLED
49 std::unique_ptr<class TfPyLock> _pyLock;
65 std::unique_ptr<Tf_SingletonInitState> initState(
66 new Tf_SingletonInitState {
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;
85 "Create Singleton " + ArchGetDemangled<T>());
90 if (Tf_SingletonInitState *initState = _initState.load()) {
91 if (initState->initThreadId == std::this_thread::get_id()) {
93 return static_cast<T *
>(initState->initInstance);
100 Tf_SingletonPyGILDropper dropGIL;
105 if (isInitializing.exchange(
true) ==
false) {
116 delete _initState.exchange(
nullptr);
119 T *curInst =
nullptr;
120 if (Tf_SingletonInitState *initState = _initState.load()) {
122 curInst =
static_cast<T *
>(initState->initInstance);
124 if (curInst && (curInst != newInst)) {
127 TF_AXIOM(instance.exchange(newInst) ==
nullptr);
129 isInitializing =
false;
133 std::this_thread::yield();
137 return instance.load();
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>
164PXR_NAMESPACE_CLOSE_SCOPE
Manage a single instance of an object (see.
static void DeleteInstance()
Destroy the sole instance object of type T, if it exists.
static void SetInstanceConstructed(T &instance)
Indicate that the sole instance object has already been created.
Demangle C++ typenames generated by the typeid() facility.
Stripped down version of diagnostic.h that doesn't define std::string.
#define TF_AXIOM(cond)
Aborts if the condition cond is not met.
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
Manage a single instance of an object.