1 #ifndef CORELIB___NCBIMTX__HPP
2 #define CORELIB___NCBIMTX__HPP
68 #ifdef NCBI_COMPILER_MSVC
70 # pragma intrinsic(_ReadWriteBarrier)
73 #if defined(NCBI_WIN32_THREADS)
74 #define NCBI_SRWLOCK_USE_NEW 1
75 #define NCBI_SEMAPHORE_USE_NEW 1
78 #if NCBI_SRWLOCK_USE_NEW || NCBI_SEMAPHORE_USE_NEW
81 # include <condition_variable>
93 # define INTERNAL_MUTEX_DEBUG
95 # undef INTERNAL_MUTEX_DEBUG
97 # define INTERNAL_MUTEX_DEBUG
110 #if defined(NCBI_NO_THREADS)
114 # define SYSTEM_MUTEX_INITIALIZER 0
116 #elif defined(NCBI_POSIX_THREADS)
120 # define SYSTEM_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
122 #elif defined(NCBI_WIN32_THREADS)
124 # define NCBI_USE_CRITICAL_SECTION
125 # define NCBI_FASTMUTEX_USE_NEW
126 # define NCBI_FASTRWLOCK_USE_NEW
128 # if defined(NCBI_FASTMUTEX_USE_NEW)
131 # elif defined(NCBI_USE_CRITICAL_SECTION)
137 # undef SYSTEM_MUTEX_INITIALIZER
140 # error "Unknown threading model."
144 #if defined(NCBI_NO_THREADS)
145 #define NCBI_NAMESPACE_MUTEX ncbi_namespace_mutex_st
147 #define NCBI_NAMESPACE_MUTEX ncbi_namespace_mutex_mt
154 #if defined(NCBI_NO_THREADS)
156 #elif defined(NCBI_POSIX_THREADS)
157 return pthread_self();
158 #elif defined(NCBI_WIN32_THREADS)
159 return GetCurrentThreadId();
164 #define THREAD_SYSTEM_ID_INITIALIZER 0
195 return m_ID == tid.
m_ID;
201 return m_ID != tid.
m_ID;
211 return m_ID == tid.
m_ID;
215 return m_ID != tid.
m_ID;
242 virtual const char* GetErrCodeString(
void)
const override;
257 class CAutoInitializeStaticMutex;
259 class CAutoInitializeStaticFastMutex;
281 eMutexUninitialized = 0,
282 eMutexInitialized = 0x2487adab
295 void Lock(ELockSemantics lock = eNormal);
299 void Unlock(ELockSemantics lock = eNormal);
315 static void ThrowUninitialized(
void);
319 static void ThrowLockFailed(
void);
323 static void ThrowUnlockFailed(
void);
327 static void ThrowTryLockFailed(
void);
329 #if !defined(NCBI_OS_MSWIN)
350 void InitializeStatic(
void);
358 void InitializeDynamic(
void);
368 void InitializeHandle(
void);
374 void DestroyHandle(
void);
377 friend class ::ncbi::CAutoInitializeStaticFastMutex;
378 friend class ::ncbi::CFastMutex;
379 friend class ::ncbi::CSafeStaticPtr_Base;
384 using NCBI_NAMESPACE_MUTEX::SSystemFastMutex;
439 static void ThrowNotOwned(
void);
441 #if !defined(NCBI_OS_MSWIN)
472 friend class ::ncbi::CAutoInitializeStaticMutex;
473 friend class ::ncbi::CMutex;
478 using NCBI_NAMESPACE_MUTEX::SSystemMutex;
489 #if defined(SYSTEM_MUTEX_INITIALIZER)
492 # define STATIC_FAST_MUTEX_INITIALIZER \
493 { SYSTEM_MUTEX_INITIALIZER, NCBI_NS_NCBI::SSystemFastMutex::eMutexInitialized }
496 # define DEFINE_STATIC_FAST_MUTEX(id) \
497 static NCBI_NS_NCBI::SSystemFastMutex id = STATIC_FAST_MUTEX_INITIALIZER
500 # define DECLARE_CLASS_STATIC_FAST_MUTEX(id) \
501 static NCBI_NS_NCBI::SSystemFastMutex id
504 # define DEFINE_CLASS_STATIC_FAST_MUTEX(id) \
505 NCBI_NS_NCBI::SSystemFastMutex id = STATIC_FAST_MUTEX_INITIALIZER
508 # define STATIC_MUTEX_INITIALIZER \
509 { STATIC_FAST_MUTEX_INITIALIZER, THREAD_SYSTEM_ID_INITIALIZER, 0 }
512 # define DEFINE_STATIC_MUTEX(id) \
513 static NCBI_NS_NCBI::SSystemMutex id = STATIC_MUTEX_INITIALIZER
516 # define DECLARE_CLASS_STATIC_MUTEX(id) \
517 static NCBI_NS_NCBI::SSystemMutex id
520 # define DEFINE_CLASS_STATIC_MUTEX(id) \
521 NCBI_NS_NCBI::SSystemMutex id = STATIC_MUTEX_INITIALIZER
526 # define NEED_AUTO_INITIALIZE_MUTEX
529 # define DEFINE_STATIC_FAST_MUTEX(id) \
530 static NCBI_NS_NCBI::CAutoInitializeStaticFastMutex id
533 # define DECLARE_CLASS_STATIC_FAST_MUTEX(id) \
534 static NCBI_NS_NCBI::CAutoInitializeStaticFastMutex id
537 # define DEFINE_CLASS_STATIC_FAST_MUTEX(id) \
538 NCBI_NS_NCBI::CAutoInitializeStaticFastMutex id
541 # define DEFINE_STATIC_MUTEX(id) \
542 static NCBI_NS_NCBI::CAutoInitializeStaticMutex id
545 # define DECLARE_CLASS_STATIC_MUTEX(id) \
546 static NCBI_NS_NCBI::CAutoInitializeStaticMutex id
549 # define DEFINE_CLASS_STATIC_MUTEX(id) \
550 NCBI_NS_NCBI::CAutoInitializeStaticMutex id
556 #if defined(NEED_AUTO_INITIALIZE_MUTEX)
569 class CAutoInitializeStaticFastMutex
572 typedef SSystemFastMutex TObject;
584 operator TObject&(void);
592 void Initialize(
void);
612 class CAutoInitializeStaticMutex
615 typedef SSystemMutex TObject;
627 operator TObject&(void);
635 void Initialize(
void);
695 operator SSystemFastMutex&(void);
698 #if !defined(NCBI_WIN32_THREADS)
703 #elif !defined(NCBI_USE_CRITICAL_SECTION)
766 operator SSystemMutex&(void);
893 #if !NCBI_SRWLOCK_USE_NEW
907 template <
class Class>
925 template <
class Class>
985 void WriteLock(
void);
993 bool TryReadLock(
void);
1001 bool TryReadLock(
const CTimeout& timeout);
1009 bool TryWriteLock(
void);
1017 bool TryWriteLock(
const CTimeout& timeout);
1023 #if NCBI_SRWLOCK_USE_NEW
1025 condition_variable m_Cv;
1027 atomic<long> m_Count;
1028 long m_WaitingWriters;
1029 vector<TThreadSystemID> m_Readers;
1030 bool m_TrackReaders;
1031 bool m_FavorWriters;
1034 vector<TThreadSystemID>::const_iterator x_FindReader(
TThreadSystemID self_id);
1036 bool x_TryReadLock();
1037 bool x_TryWriteLock();
1041 fTrackReaders = 0x40000000
1069 template <
class Class>
1088 template <
class Class>
1144 void ReadLock(
void);
1146 void ReadUnlock(
void);
1149 void WriteLock(
void);
1151 void WriteUnlock(
void);
1159 kWriteLockValue = 0x100000
1162 #if defined(NCBI_WIN32_THREADS) && defined(NCBI_FASTRWLOCK_USE_NEW)
1273 void x_OnLockAcquired(
void);
1277 void x_OnLockReleased(
void);
1280 virtual void DeleteThis(
void);
1382 CSemaphore(
unsigned int init_count,
unsigned int max_count);
1400 bool TryWait(
unsigned int timeout_sec = 0,
unsigned int timeout_nsec = 0);
1403 bool TryWait(
const CTimeout& timeout);
1408 void Post(
unsigned int count = 1);
1411 #if NCBI_SEMAPHORE_USE_NEW
1413 condition_variable m_Cv;
1414 const unsigned int m_Max;
1415 unsigned int m_Count;
1416 bool x_TryAcquire(
void);
1436 #if defined(NCBI_POSIX_THREADS) || (defined(NCBI_WIN32_THREADS) && (defined(NCBI_USE_CRITICAL_SECTION) || defined(NCBI_FASTMUTEX_USE_NEW)))
1437 # define NCBI_HAVE_CONDITIONAL_VARIABLE
1446 static bool IsSupported(
void);
1490 void SignalSome(
void);
1494 void SignalAll(
void);
1496 #if defined(NCBI_THREADS)
1498 bool x_WaitForSignal(SSystemFastMutex& mutex,
const CDeadline& timeout);
1500 #if defined(NCBI_OS_MSWIN)
1503 pthread_cond_t m_ConditionVar;
1543 virtual const char* GetErrCodeString(
void)
const override;
CAtomicCounter_WithAutoInit –.
CConditionVariableException –.
CNoLock is a simple no-op lock which does no real locking.
Holder of the lock inside CYieldingRWLock.
CTimeout – Timeout interval.
Read/write lock without blocking calls.
Interface for factory creating CRWLockHolder objects.
Interface for receiving messages about state changes in CRWLockHolder.
EErrCode
Error types that an application can generate.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
volatile unsigned int m_WaitingWriters
Number of writers waiting; zero if not keeping track.
CWriteLockGuard TWriteLockGuard
Define Write Lock Guard.
CSpinLock(const CSpinLock &)
Prohibit copying of the object.
TWriteLockGuard CWriteLockGuard
CGuard< CRWLock, SSimpleReadLock< CRWLock > > TReadLockGuard
bool operator!=(const CThreadSystemID &tid) const
Non-equality operator for thread ID.
ERWLockType
Type of locking provided by CYieldingRWLock.
CGuard< CFastRWLock, SSimpleReadLock< CFastRWLock >, SSimpleReadUnlock< CFastRWLock > > CFastReadGuard
ELockSemantics
This is for condition variables.
CSpinGuard TWriteLockGuard
Define Write Lock Guard.
CMutex(const CMutex &)
Private copy constructor to disallow initialization.
unique_ptr< CInternalRWLock > m_RW
Platform-dependent RW-lock data.
CRWLockHolder(const CRWLockHolder &)
CGuard< SSystemFastMutex > TFastMutexGuard
typedefs for ease of use
struct SSemaphore * m_Sem
System-specific semaphore data.
CFastMutexGuard TReadLockGuard
Define Read Lock Guard.
EFlags
Flags (passed at construction time) for fine-tuning lock behavior.
CFastRWLock(const CFastRWLock &)
friend class CYieldingRWLock
bool TryLock(void)
Attempt to lock the mutex and return TRUE if it succeeded or FALSE if mutex is locked by other thread...
CFastMutex(const CFastMutex &)
Private copy constructor to disallow initialization.
void operator()(Class &inst) const
void Lock(void)
Acquire mutex for the current thread with no nesting checks.
bool IsInitialized(void) const
Check if mutex is initialized.
CRWLockHolder(IRWLockHolder_Factory *factory)
Create lock holder bound to given object factory.
void Lock(void)
Lock mutex.
TFastMutexGuard CFastMutexGuard
...and backward compatibility
TReadLockGuard CReadLockGuard
bool IsLocked(void)
Check if any type of lock on this object is held.
TSystemMutex * GetHandle(void)
Get handle - Unix version.
EMagic
Initialization flag values.
CReadLockGuard TReadLockGuard
Define Read Lock Guard.
void InitializeDynamic(void)
Initialize dynamic mutex.
CSpinLock & operator=(const CSpinLock &)
CNoLock CNoMutex
CNoMutex –.
ERWLockType m_Type
Type of lock held.
~CFastMutex(void)
Destructor.
CFastMutex(void)
Constructor.
static CThreadSystemID GetCurrent(void)
Get the current thread ID.
virtual void OnLockAcquired(CRWLockHolder *holder)=0
Callback called when lock represented by CRWLockHolder is acquired.
CGuard< CSpinLock > CSpinGuard
bool IsLockAcquired(void) const
Check if lock requested is already granted.
CFastMutex m_WriteLock
Mutex implementing write lock.
CGuard< CRWLock, SSimpleWriteLock< CRWLock > > TWriteLockGuard
CYieldingRWLock * GetRWLock(void) const
Get lock object that is locked by this holder.
void Reset(void)
Reset holder to be able to use it later (after calling Init() )
bool operator==(const CThreadSystemID &tid) const
Equality operator for thread ID.
TThreadSystemID TID
Define a simpler alias for TThreadSystemID.
CSpinLock m_ObjLock
Main locking mutex for object operations.
CRef< CRWLockHolder > TRWLockHolderRef
Type that should be always used to store pointers to CRWLockHolder.
CMutexGuard TWriteLockGuard
Define Write Lock Guard.
SSystemFastMutex m_Mutex
Mutex value.
TFlags m_Flags
Configuration flags.
virtual void OnLockReleased(CRWLockHolder *holder)=0
Callback called when lock represented by CRWLockHolder is released.
bool IsLocked(void) const
Check if mutex is currently locked.
THoldersList m_LockWaits
Queue for waiting lock requests.
TRWLockHolderRef AcquireWriteLock(void)
Write lock.
CIRef< IRWLockHolder_Listener > TRWLockHolder_ListenerRef
Types of smart references to IRWLockHolder_Listener.
virtual CRWLockHolder * CreateHolder(CYieldingRWLock *lock, ERWLockType typ)=0
Obtain new CRWLockHolder object for given CYieldingRWLock and necessary lock type.
vector< TThreadSystemID > m_Readers
List of all readers or writers.
CSemaphore(const CSemaphore &)
Private copy constructor to disallow initialization.
volatile long m_Count
Number of readers (if >0) or writers (if <0)
SSystemFastMutex *volatile m_WaitMutex
void RemoveListener(IRWLockHolder_Listener *listener)
Remove object keeping track of holder state changes.
SSystemFastMutex m_Mutex
Platform-dependent mutex handle, also used by CRWLock.
IRWLockHolder_Factory * m_Factory
Factory created the holder.
bool TryLock(void)
Try locking mutex.
CGuard< SSystemMutex > TMutexGuard
typedefs for ease of use
void Set(const CThreadSystemID &tid) volatile
volatile versions of above methods
TListenersList m_Listeners
List of holder listeners.
IRWLockHolder_Factory * m_Factory
Factory creating CRWLockHolder objects.
bool Is(const CThreadSystemID &tid) const volatile
bool IsNot(const CThreadSystemID &tid) const volatile
pthread_mutex_t TSystemMutex
Define a platform independent system mutex.
void AddListener(IRWLockHolder_Listener *listener)
Add object keeping track of holder state changes.
volatile EMagic m_Magic
Magic flag.
CAtomicCounter_WithAutoInit m_WaitCounter
CFastMutexGuard TWriteLockGuard
Define Write Lock Guard.
volatile TThreadSystemID m_Owner
Writer ID, one of the readers ID.
void Init(CYieldingRWLock *lock, ERWLockType typ)
Initialize holder for given CYieldingRWLock and necessary lock type.
bool IsUninitialized(void) const
Check if mutex is un-initialized.
void Unlock(void)
Unlock the mutex.
void ReleaseLock(void)
Release the lock held or cancel request for the lock.
CRWLock(const CRWLock &)
Private copy constructor to disallow initialization.
CMutex & operator=(const CMutex &)
Private assignment operator to disallow assignment.
virtual void DeleteHolder(CRWLockHolder *holder)=0
Free unnecessary (and unreferenced by anybody) CRWLockHolder object.
CWeakIRef< IRWLockHolder_Listener > TRWLockHolder_ListenerWeakRef
NCBI_EXCEPTION_DEFAULT(CConditionVariableException, CCoreException)
NCBI_EXCEPTION_DEFAULT(CMutexException, CCoreException)
CAtomicCounter m_LockCount
Number of read locks acquired or value of kWriteLockValue if write lock was acquired.
CSpinGuard TReadLockGuard
Define Read Lock Guard.
CFastMutex & operator=(const CFastMutex &)
Private assignment operator to disallow assignment.
void Unlock(void)
Unlock mutex.
bool IsUninitialized(void) const
Check if mutex is un-initialized.
void InitializeStatic(void)
Initialize static mutex.
SSystemMutex m_Mutex
System mutex.
void operator()(Class &inst) const
void operator()(Class &inst) const
CFastWriteGuard TWriteLockGuard
deque< TRWLockHolderRef > THoldersList
IRWLockHolder_Factory * GetFactory(void) const
Get factory which this object was created from.
bool IsInitialized(void) const
Check if mutex is initialized.
void Lock(void)
Lock the mutex.
list< TRWLockHolder_ListenerWeakRef > TListenersList
TMutexGuard CMutexGuard
...and backward compatibility
CYieldingRWLock * m_Lock
Lock object the holder is assigned to.
void operator()(Class &inst) const
CONDITION_VARIABLE m_ConditionVar
pthread_t TThreadSystemID
Define platform-dependent thread ID type.
atomic< TThreadSystemID > m_Owner
Platform-dependent owner thread ID.
TRWLockHolderRef AcquireReadLock(void)
Read lock.
CMutexGuard TReadLockGuard
Define Read Lock Guard.
atomic< int > m_Count
# of recursive (in the same thread) locks
CFastReadGuard TReadLockGuard
CGuard< CFastRWLock, SSimpleWriteLock< CFastRWLock >, SSimpleWriteUnlock< CFastRWLock > > CFastWriteGuard
CSpinLock m_ObjLock
Mutex for operating listeners.
int TFlags
binary OR of EFlags
void *volatile m_Value
Flag showing if mutex is locked (non-NULL value) or unlocked (NULL value).
TSystemMutex m_Handle
Mutex handle.
void Unlock(void)
Release mutex with no owner or nesting checks.
void CheckInitialized(void) const
Check initialized value of mutex.
bool m_LockAcquired
Flag if lock was acquired.
static TThreadSystemID GetCurrentThreadSystemID(void)
Get the current thread ID.
bool TryLock(void)
Try locking the mutex.
ERWLockType GetLockType(void) const
Get type of lock held.
#define NCBI_NAMESPACE_MUTEX
@ eTryLock
Attempted lock error.
@ eInfinite
Infinite deadline.
#define NCBI_XNCBI_EXPORT
#define HANDLE
An abstraction for a file handle.
const TYPE & Get(const CNamedParameterList *param)
Portable reference counted smart and weak pointers using CWeakRef, CRef, CObject and CObjectEx.
Multi-threading configuration.
Defines: CTimeFormat - storage class for time format.