1 #ifndef NCBI_SAFE_STATIC__HPP
2 #define NCBI_SAFE_STATIC__HPP
76 eLifeSpan_Shortest = -20000,
77 eLifeSpan_Short = -10000,
79 eLifeSpan_Long = 10000,
80 eLifeSpan_Longest = 20000
119 typedef void (*FUserCleanup)(
void* ptr);
146 FUserCleanup user_cleanup = 0,
147 TLifeSpan life_span = TLifeSpan::GetDefault())
148 : m_SelfCleanup(self_cleanup),
149 m_UserCleanup(user_cleanup),
150 m_LifeSpan(life_span),
151 m_CreationOrder(x_GetCreationOrder())
161 return m_Ptr.load(memory_order_acquire);
164 m_Ptr.store(ptr, memory_order_release);
167 return x_GetPtr() !=
nullptr;
170 if (
auto ptr = x_GetPtr() ) {
186 if (!m_InstanceMutex || !m_MutexRefCount) {
187 m_InstanceMutex =
new CMutex;
192 m_InstanceMutex->Lock();
197 m_InstanceMutex->Unlock();
198 x_ReleaseInstanceMutex();
204 if (--m_MutexRefCount > 0)
return;
224 static int x_GetCreationOrder(
void);
239 if ( m_SelfCleanup ) {
241 m_SelfCleanup(
this, guard);
244 x_ReleaseInstanceMutex();
301 static void DisableChildThreadsCheck();
318 const size_t index = level;
320 _ASSERT(index < stacks.size());
321 return stacks[index];
325 static void x_Cleanup(
CMutexGuard& guard, TStack*& stack);
359 if (ptr)
delete static_cast<T*
>(ptr);
363 if (ptr)
delete const_cast<T*
>(
static_cast<const T*
>(ptr));
388 typedef T* (*FCreate)(void);
450 return static_cast<T*
>(
const_cast<void*
>(ptr));
539 "CSafeStatic::Init: Register() failed");
563 template<
class T,
class V, V value>
574 #define SAFE_CONST_STATIC(type, init_value) \
575 SAFE_CONST_STATIC_EX(type, type, init_value)
579 #define SAFE_CONST_STATIC_EX(type, init_value_type, init_value) \
580 CSafeStatic< const type, \
581 CSafeStaticInit_Callbacks<const type, init_value_type, init_value> >
584 #define SAFE_CONST_STATIC_STRING(var, value) \
585 char SAFE_CONST_STATIC_STRING_##var[] = value; \
586 SAFE_CONST_STATIC_EX(std::string, const char*, \
587 SAFE_CONST_STATIC_STRING_##var) var
606 return static_cast<T*
>(
const_cast<void*
>(ptr));
634 template <
class FUserCreate>
636 T&
Get(FUserCreate user_create)
657 template <
class FUserCreate>
658 void x_Init(FUserCreate user_create);
668 if ( user_cleanup ) {
692 return static_cast<T*
>(
const_cast<void*
>(ptr));
720 template <
class FUserCreate>
722 T&
Get(FUserCreate user_create)
742 template <
class FUserCreate>
753 if ( user_cleanup ) {
756 ptr->RemoveReference();
780 if ( !x_IsSetPtr() ) {
795 if ( !x_IsSetPtr() ) {
804 template <
class FUserCreate>
809 if ( !x_IsSetPtr() ) {
811 if (
auto ptr = user_create() ) {
824 if ( !x_IsSetPtr() ) {
827 object->AddReference();
840 if ( !x_IsSetPtr() ) {
851 template <
class FUserCreate>
856 if ( !x_IsSetPtr() ) {
858 T* ptr = user_create();
void Release()
Manually force the resource to be released.
static void Register(CSafeStaticPtr_Base *ptr)
Add new on-demand variable to the cleanup stack.
static TStack *& x_GetStack(CSafeStaticLifeSpan::ELifeLevel level)
static bool sm_ChildThreadsCheck
multiset< CSafeStaticPtr_Base *, CSafeStatic_Less > TStack
Safe static callbacks version allowing initial value of type V.
ELifeLevel GetLifeLevel() const
Get life level value.
static CSafeStaticLifeSpan & GetDefault(void)
Get default life span (set to eLifeSpan_Min).
int GetLifeSpan(void) const
Get life span value.
ELifeSpan
Predefined life spans for the safe static objects.
@ eLifeSpan_Min
std static, not adjustable
ELifeLevel
Predefined life levels for the safe static objects.
DECLARE_CLASS_STATIC_MUTEX(sm_ClassMutex)
void(* FUserCleanup)(void *ptr)
User cleanup function type.
const void * x_GetPtr() const
CGuard< CSafeStaticPtr_Base > TInstanceMutexGuard
CSafeStaticPtr_Base(FSelfCleanup self_cleanup, FUserCleanup user_cleanup=0, TLifeSpan life_span=TLifeSpan::GetDefault())
Constructor.
FUserCleanup m_UserCleanup
CSafeStaticLifeSpan TLifeSpan
Life span.
void x_ReleaseInstanceMutex(void)
bool x_IsStdStatic(void) const
atomic< const void * > m_Ptr
Pointer to the data.
FSelfCleanup m_SelfCleanup
void x_SetPtr(const void *ptr)
const void * x_ReleasePtr()
static void sx_SelfCleanup(CSafeStaticPtr_Base *safe_static, TInstanceMutexGuard &guard)
CSafeStaticLifeSpan TLifeSpan
static T * x_CastPtr(const void *ptr)
T & Get(FUserCreate user_create)
Get the existing object or create a new one using the provided FUserCreate object.
void Set(T *object)
Initialize with an existing object.
CSafeStaticPtr(FUserCleanup user_cleanup=0, TLifeSpan life_span=TLifeSpan::GetDefault())
Constructor.
T & Get(void)
Create the variable if not created yet, return the reference.
T & Get(void)
Create the variable if not created yet, return the reference.
static void sx_SelfCleanup(CSafeStaticPtr_Base *safe_static, TInstanceMutexGuard &guard)
void x_Init(FUserCreate user_create)
static T * x_CastPtr(const void *ptr)
void Set(T *object)
Initialize with an existing object.
T & Get(FUserCreate user_create)
Get the existing object or create a new one using the provided FUserCreate object.
CSafeStaticLifeSpan TLifeSpan
CSafeStaticRef(FUserCleanup user_cleanup=0, TLifeSpan life_span=TLifeSpan::GetDefault())
Constructor.
Helper class for object allocation/deallocation.
static void s_RemoveReference(CObject *ptr)
static void s_RemoveReference(const CObject *ptr)
static void s_RemoveReference(const void *ptr)
static void s_AddReference(const void *)
static void s_AddReference(void *)
static void s_RemoveReference(void *ptr)
static void s_AddReference(CObject *ptr)
static T * s_Create(void)
Create a new class instance.
Initialization and cleanup of a safe-static object.
CSafeStatic_Callbacks(FCreate create=0, FCleanup cleanup=0)
The constructor allows to use CSafeStatic_Callbacks as a simple wrapper for static functions.
void Cleanup(T &value)
Perform cleanup before destruction.
T * Create(void)
Create new object.
void(* FCleanup)(T &value)
T *(* FCreate)(void)
The default implementation allows to use callback functions rather than a new class.
CSafeStatic_Allocator< T > TAllocator
Comparison for safe static ptrs.
bool operator()(const TPtr &ptr1, const TPtr &ptr2) const
CSafeStaticPtr_Base * TPtr
CSafeStatic_Callbacks< T >::FCreate FCreate
Callback function types.
CSafeStatic_Allocator< T > TAllocator
CSafeStatic & operator=(const CSafeStatic &)=delete
CSafeStatic(FCreate create, FCleanup cleanup, TLifeSpan life_span=TLifeSpan::GetDefault())
Constructor.
static void sx_SelfCleanup(CSafeStaticPtr_Base *safe_static, TInstanceMutexGuard &guard)
CSafeStaticLifeSpan TLifeSpan
T & Get(void)
Create the variable if not created yet, return the reference.
CSafeStatic(const CSafeStatic &)=delete
CSafeStatic(TLifeSpan life_span=TLifeSpan::GetDefault())
Constructor.
CSafeStatic< T, TCallbacks > TThisType
CSafeStatic_Callbacks< T >::FCleanup FCleanup
static T * x_CastPtr(const void *ptr)
CSafeStatic(TCallbacks callbacks, TLifeSpan life_span=TLifeSpan::GetDefault())
Constructor.
static void cleanup(void)
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
#define NCBI_RETHROW_SAME(prev_exception, message)
Generic macro to re-throw the same exception.
void AddReference(void) const
Add reference to object.
void RemoveReference(void) const
Remove reference to object.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
void Cleanup(CTls< TValue > &value)
#define NCBI_XNCBI_EXPORT
unsigned int
A callback function used to compare two keys in a database.
const GenericPointer< typename T::ValueType > T2 value
static CSafeStaticGuard s_CleanupGuard
This static variable must be present in all modules using on-demand static variables.
Multi-threading – mutexes; rw-locks; semaphore.
Portable reference counted smart and weak pointers using CWeakRef, CRef, CObject and CObjectEx.
SSimpleLock is a functor to wrap calling Lock().
SSimpleLock is a functor to wrap calling Unlock().