8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
16#if ALIB_DEBUG && !ALIB_STRINGS
32#if !ALIB_SINGLE_THREADED
52 Dbg.AssertNotOwning(
ALIB_CALLER, ci,
"Illegal nested acquisition" );
54 if ( !
Dbg.WaitTimeLimit.IsZero() )
56 Ticks::Duration waitDuration=
Dbg.WaitTimeLimit;
59 while (!
mutex.try_lock_for( (waitDuration - waitTimer.
Age()).Export() ) )
61 if ( waitTimer.
Age() < waitDuration )
65 NAString msg(
"Waiting to acquire a lock since "); msg << overallTimer.
Age();
68 std::string msg(
"Waiting to acquire a lock since ");
69 msg+= std::format(
"{}", overallTimer.
Age().InAbsoluteMilliseconds());
80 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
81 Dbg.CntAcquirements++;
87 Dbg.AssertNotOwning(
ALIB_CALLER, ci,
"Illegal nested acquisition" );
89 if (!
mutex.try_lock() )
92 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
93 Dbg.CntAcquirements++;
102 Dbg.AssertOwning(
ALIB_CALLER, ci,
"Acquired by a different thread");
104 Dbg.CntAcquirements--;
116 Ticks::Duration remainingDuration= waitDuration;
118 while (!
mutex.try_lock_for( remainingDuration.Export() ) )
120 remainingDuration= waitDuration - timer.
Age();
121 if ( remainingDuration.IsPositive() )
131 Dbg.AssertNotOwning(
ALIB_CALLER, ci,
"Illegal nested acquisition" );
133 if ( !
Dbg.WaitTimeLimit.IsZero() )
135 Ticks::Duration waitDuration=
Dbg.WaitTimeLimit;
138 while (!
mutex.try_lock_for( (waitDuration - waitTimer.
Age()).Export() ) )
140 if ( waitTimer.
Age() < waitDuration )
144 NAString msg(
"Waiting to acquire a lock since "); msg << overallTimer.
Age();
147 std::string msg(
"Waiting to acquire a lock since ");
148 msg+= std::format(
"{}", overallTimer.
Age().InAbsoluteMilliseconds());
159 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
160 Dbg.CntAcquirements++;
166 Dbg.AssertNotOwning(
ALIB_CALLER, ci,
"Illegal nested acquisition" );
168 if (!
mutex.try_lock() )
171 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
173 Dbg.CntAcquirements++;
181 Dbg.AssertNotOwning(
ALIB_CALLER, ci,
"Illegal nested acquisition" );
183 Ticks::Duration remainingDuration= waitDuration;
185 while (!
mutex.try_lock_for( remainingDuration.Export() ) )
187 remainingDuration= waitDuration - timer.
Age();
188 if ( remainingDuration.IsPositive() )
193 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
195 Dbg.CntAcquirements++;
202 Dbg.AssertOwning(
ALIB_CALLER, ci,
"Acquired by a different thread");
204 Dbg.CntAcquirements--;
213 if ( !
Dbg.WaitTimeLimit.IsZero() )
215 Ticks::Duration waitDuration=
Dbg.WaitTimeLimit;
218 while (!
mutex.try_lock_for( (waitDuration - waitTimer.
Age()).Export() ) )
220 if ( waitTimer.
Age() < waitDuration )
224 NAString msg(
"Waiting to acquire a lock since "); msg << overallTimer.
Age();
227 std::string msg(
"Waiting to acquire a lock since ");
228 msg+= std::format(
"{}", overallTimer.
Age().InAbsoluteMilliseconds());
238 Dbg.AssertNotOwnedOrMe(
ALIB_CALLER, ci,
"Still owned after locking" );
239 Dbg.CntAcquirements++;
241 if(
Dbg.RecursionLimit != 0
242 && (
Dbg.CntAcquirements %
Dbg.RecursionLimit) == 0 ) {
244 NAString msg; msg <<
Dbg.CntAcquirements <<
" recursive acquisitions."
245 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
248 std::string msg; msg+= std::format(
"{}",
Dbg.CntAcquirements);
249 msg+=
" recursive acquisitions."
250 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
258 if (!
mutex.try_lock() )
261 Dbg.AssertNotOwnedOrMe(
ALIB_CALLER, ci,
"Still owned after locking" );
262 Dbg.CntAcquirements++;
264 if(
Dbg.RecursionLimit != 0
265 && (
Dbg.CntAcquirements %
Dbg.RecursionLimit) == 0 ) {
267 NAString msg; msg <<
Dbg.CntAcquirements <<
" recursive acquisitions."
268 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
271 std::string msg; msg+= std::format(
"{}",
Dbg.CntAcquirements);
272 msg+=
" recursive acquisitions."
273 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
286 if(--
Dbg.CntAcquirements >= 0)
294 Ticks::Duration remainingDuration= waitDuration;
296 while (!
mutex.try_lock_for( remainingDuration.Export() ) )
298 remainingDuration= waitDuration - timer.
Age();
299 if ( remainingDuration.IsPositive() )
308 if ( !
Dbg.WaitTimeLimit.IsZero() )
310 Ticks::Duration waitDuration=
Dbg.WaitTimeLimit;
313 while (!
mutex.try_lock_for( (waitDuration - waitTimer.
Age()).Export() ) )
315 if ( waitTimer.
Age() < waitDuration )
319 NAString msg(
"Waiting to acquire a lock since "); msg << overallTimer.
Age();
322 std::string msg(
"Waiting to acquire a lock since ");
323 msg+= std::format(
"{}", overallTimer.
Age().InAbsoluteMilliseconds());
334 Dbg.AssertNotOwnedOrMe(
ALIB_CALLER, ci,
"Still owned after locking" );
335 Dbg.CntAcquirements++;
337 if(
Dbg.RecursionLimit != 0
338 && (
Dbg.CntAcquirements %
Dbg.RecursionLimit) == 0 ) {
340 NAString msg; msg <<
Dbg.CntAcquirements <<
" recursive acquisitions."
341 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
344 std::string msg; msg+= std::format(
"{}",
Dbg.CntAcquirements);
345 msg+=
" recursive acquisitions."
346 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
354 if (!
mutex.try_lock() )
357 Dbg.AssertNotOwnedOrMe(
ALIB_CALLER, ci,
"Still owned after locking" );
358 Dbg.CntAcquirements++;
360 if(
Dbg.RecursionLimit != 0
361 && (
Dbg.CntAcquirements %
Dbg.RecursionLimit) == 0 ) {
363 NAString msg; msg <<
Dbg.CntAcquirements <<
" recursive acquisitions."
364 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
367 std::string msg; msg+= std::format(
"{}",
Dbg.CntAcquirements);
368 msg+=
" recursive acquisitions."
369 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
379 Ticks::Duration remainingDuration= waitDuration;
381 while (!
mutex.try_lock_for( remainingDuration.Export() ) )
383 remainingDuration= waitDuration - timer.
Age();
384 if ( remainingDuration.IsPositive() )
389 Dbg.AssertNotOwnedOrMe(
ALIB_CALLER, ci,
"Still owned after locking" );
390 Dbg.CntAcquirements++;
392 if(
Dbg.RecursionLimit != 0
393 && (
Dbg.CntAcquirements %
Dbg.RecursionLimit) == 0 ) {
395 NAString msg; msg <<
Dbg.CntAcquirements <<
" recursive acquisitions."
396 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
399 std::string msg; msg+= std::format(
"{}",
Dbg.CntAcquirements);
400 msg+=
" recursive acquisitions."
401 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
413 Dbg.CntAcquirements--;
422 Dbg.AssertNotOwning(
ALIB_CALLER, ci,
"Illegal nested acquisition" );
424 if ( !
Dbg.WaitTimeLimit.IsZero() )
426 Ticks::Duration waitDuration=
Dbg.WaitTimeLimit;
429 while (!
mutex.try_lock_for( (waitDuration - waitTimer.
Age()).Export() ) )
431 if ( waitTimer.
Age() < waitDuration )
435 NAString msg(
"Waiting to acquire a lock since "); msg << overallTimer.
Age();
438 std::string msg(
"Waiting to acquire a lock since ");
439 msg+= std::format(
"{}", overallTimer.
Age().InAbsoluteMilliseconds());
450 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
451 Dbg.CntAcquirements++;
457 Dbg.AssertNotOwning(
ALIB_CALLER, ci,
"Illegal nested acquisition" );
459 if (!
mutex.try_lock() )
462 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
463 Dbg.CntAcquirements++;
473 Dbg.CntAcquirements--;
481 "AcquireShared while already owning. (This is not allowed with std::shared_lock)" );
483 if ( !
Dbg.WaitTimeLimit.IsZero() )
485 Ticks::Duration waitDuration=
Dbg.WaitTimeLimit;
488 while (!
mutex.try_lock_shared_for( (waitDuration - waitTimer.
Age()).Export() ) )
490 if ( waitTimer.
Age() < waitDuration )
494 NAString msg(
"Waiting to acquire a lock since "); msg << overallTimer.
Age();
497 std::string msg(
"Waiting to acquire a lock since ");
498 msg+= std::format(
"{}", overallTimer.
Age().InAbsoluteMilliseconds());
511 "Too many parallel shared acquisitions detected. "
512 "A reason might be that shared acquirers do not call ReleaseShared" );
520 "AcquireShared while already owning. (This is not allowed with std::shared_lock)" );
522 if ( !
mutex.try_lock_shared() )
528 "Too many parallel shared acquisitions detected. "
529 "A reason might be that shared acquirers do not call ReleaseShared" );
537 auto prevCounter=
Dbg.CntSharedAcquirements.fetch_sub(1);
538 if ( prevCounter <= 0 )
540 "Too many invocations of ReleaseShared (from any thread) without prior acquisition" );
543 mutex.unlock_shared();
550 Ticks::Duration remainingDuration= waitDuration;
552 while (!
mutex.try_lock_for( remainingDuration.Export() ) )
554 remainingDuration= waitDuration - timer.
Age();
555 if ( remainingDuration.IsPositive() )
564 Dbg.AssertNotOwning(
ALIB_CALLER, ci,
"Illegal nested acquisition" );
566 if ( !
Dbg.WaitTimeLimit.IsZero() )
568 Ticks::Duration waitDuration=
Dbg.WaitTimeLimit;
571 while (!
mutex.try_lock_for( (waitDuration - waitTimer.
Age()).Export() ) )
573 if ( waitTimer.
Age() < waitDuration )
577 NAString msg(
"Waiting to acquire a lock since "); msg << overallTimer.
Age();
580 std::string msg(
"Waiting to acquire a lock since ");
581 msg+= std::format(
"{}", overallTimer.
Age().InAbsoluteMilliseconds());
592 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
593 Dbg.CntAcquirements++;
598 Dbg.AssertNotOwning(
ALIB_CALLER, ci,
"Illegal nested acquisition" );
600 if (!
mutex.try_lock() )
603 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
604 Dbg.CntAcquirements++;
612 Dbg.AssertNotOwning(
ALIB_CALLER, ci,
"Illegal nested acquisition" );
614 Ticks::Duration remainingDuration= waitDuration;
616 while (!
mutex.try_lock_for( remainingDuration.Export() ) )
618 remainingDuration= waitDuration - timer.
Age();
619 if ( remainingDuration.IsPositive() )
624 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
625 Dbg.CntAcquirements++;
635 Dbg.CntAcquirements--;
644 Ticks::Duration remainingDuration= waitDuration;
646 while (!
mutex.try_lock_shared_for( remainingDuration.Export() ) )
648 remainingDuration= waitDuration - timer.
Age();
649 if ( remainingDuration.IsPositive() )
661 "AcquireShared while already owning. (This is not allowed with std::shared_lock)" );
663 if ( !
Dbg.WaitTimeLimit.IsZero() )
665 Ticks::Duration waitDuration=
Dbg.WaitTimeLimit;
668 while (!
mutex.try_lock_shared_for( (waitDuration - waitTimer.
Age()).Export() ) )
670 if ( waitTimer.
Age() < waitDuration )
674 NAString msg(
"Waiting to acquire a lock since "); msg << overallTimer.
Age();
677 std::string msg(
"Waiting to acquire a lock since ");
678 msg+= std::format(
"{}", overallTimer.
Age().InAbsoluteMilliseconds());
689 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
693 "Too many parallel shared acquisitions detected. "
694 "A reason might be that shared acquirers do not call ReleaseShared" );
702 "AcquireShared while already owning. (This is not allowed with std::shared_lock)" );
704 if ( !
mutex.try_lock_shared() )
707 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
711 "Too many parallel shared acquisitions detected. "
712 "A reason might be that shared acquirers do not call ReleaseShared" );
722 "AcquireShared while already owning. (This is not allowed with std::shared_lock)" );
724 Ticks::Duration remainingDuration= waitDuration;
726 while (!
mutex.try_lock_shared_for( remainingDuration.Export() ) )
728 remainingDuration= waitDuration - timer.
Age();
729 if ( remainingDuration.IsPositive() )
734 Dbg.AssertNotOwned(
ALIB_CALLER, ci,
"Still owned after locking" );
738 "Too many parallel shared acquisitions detected. "
739 "A reason might be that shared acquirers do not call ReleaseShared" );
747 auto prevCounter=
Dbg.CntSharedAcquirements.fetch_sub(1);
748 if ( prevCounter <= 0 )
750 "Too many invocations of ReleaseShared (from any thread) without prior acquisition" );
753 mutex.unlock_shared();
758#if ALIB_DEBUG_CRITICAL_SECTIONS
759bool Lock ::DCSIsAcquired()
const {
return Dbg.IsOwnedByCurrentThread(); }
760bool Lock ::DCSIsSharedAcquired()
const {
return Dbg.IsOwnedByCurrentThread(); }
761bool TimedLock ::DCSIsAcquired()
const {
return Dbg.IsOwnedByCurrentThread(); }
762bool TimedLock ::DCSIsSharedAcquired()
const {
return Dbg.IsOwnedByCurrentThread(); }
763bool RecursiveLock ::DCSIsAcquired()
const {
return Dbg.IsOwnedByCurrentThread(); }
764bool RecursiveLock ::DCSIsSharedAcquired()
const {
return Dbg.IsOwnedByCurrentThread(); }
767bool SharedLock ::DCSIsAcquired()
const {
return Dbg.IsOwnedByCurrentThread(); }
768bool SharedLock ::DCSIsSharedAcquired()
const {
return Dbg.IsSharedOwnedByAnyThread()
769 ||
Dbg.IsOwnedByCurrentThread(); }
770bool SharedTimedLock ::DCSIsAcquired()
const {
return Dbg.IsOwnedByCurrentThread(); }
771bool SharedTimedLock ::DCSIsSharedAcquired()
const {
return Dbg.IsSharedOwnedByAnyThread()
772 ||
Dbg.IsOwnedByCurrentThread(); }
DbgLockAsserter Dbg
The debug tool instance.
ALIB_DLL void Release(ALIB_DBG_TAKE_CI)
ALIB_DLL bool TryAcquire(ALIB_DBG_TAKE_CI)
ALIB_DLL void Acquire(ALIB_DBG_TAKE_CI)
ALIB_DLL void AcquireRecursive(ALIB_DBG_TAKE_CI)
std::recursive_mutex mutex
ALIB_DLL void ReleaseRecursive(ALIB_DBG_TAKE_CI)
ALIB_DLL bool TryAcquire(ALIB_DBG_TAKE_CI)
DbgLockAsserter Dbg
The debug tool instance.
ALIB_DLL void ReleaseRecursive(ALIB_DBG_TAKE_CI)
DbgLockAsserter Dbg
The debug tool instance.
virtual ALIB_DLL bool DCSIsAcquired() const override
std::recursive_timed_mutex mutex
The internal object to lock on.
virtual ALIB_DLL bool DCSIsSharedAcquired() const override
ALIB_DLL bool TryAcquireTimed(const Ticks::Duration &waitDuration, const CallerInfo &ci)
ALIB_DLL void AcquireRecursive(ALIB_DBG_TAKE_CI)
ALIB_DLL bool TryAcquire(ALIB_DBG_TAKE_CI)
ALIB_DLL bool TryAcquire(ALIB_DBG_TAKE_CI)
std::atomic< int > DbgWarningMaximumShared
ALIB_DLL void Release(ALIB_DBG_TAKE_CI)
DbgSharedLockAsserter Dbg
The debug tool instance.
ALIB_DLL void ReleaseShared(ALIB_DBG_TAKE_CI)
ALIB_DLL void AcquireShared(ALIB_DBG_TAKE_CI)
ALIB_DLL bool TryAcquireShared(ALIB_DBG_TAKE_CI)
ALIB_DLL void Acquire(ALIB_DBG_TAKE_CI)
DbgSharedLockAsserter Dbg
The debug tool instance.
std::shared_timed_mutex mutex
The internal object to lock on.
ALIB_DLL void AcquireShared(ALIB_DBG_TAKE_CI)
ALIB_DLL void Acquire(ALIB_DBG_TAKE_CI)
ALIB_DLL bool TryAcquireShared(ALIB_DBG_TAKE_CI)
std::atomic< int > DbgWarningMaximumShared
ALIB_DLL void ReleaseShared(ALIB_DBG_TAKE_CI)
ALIB_DLL bool TryAcquireTimed(const Ticks::Duration &waitDuration, const CallerInfo &ci)
ALIB_DLL bool TryAcquireSharedTimed(const Ticks::Duration &waitDuration, const CallerInfo &ci)
ALIB_DLL void Release(ALIB_DBG_TAKE_CI)
ALIB_DLL bool TryAcquire(ALIB_DBG_TAKE_CI)
DbgLockAsserter Dbg
The debug tool instance.
ALIB_DLL bool TryAcquireTimed(const Ticks::Duration &waitDuration, const CallerInfo &ci)
ALIB_DLL void Release(ALIB_DBG_TAKE_CI)
std::timed_mutex mutex
The internal object to lock on.
ALIB_DLL bool TryAcquire(ALIB_DBG_TAKE_CI)
ALIB_DLL void Acquire(ALIB_DBG_TAKE_CI)
ALIB_DLL Lock STD_IOSTREAMS_LOCK
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace alib.
lang::CallerInfo CallerInfo
Type alias in namespace alib.
time::Ticks Ticks
Type alias in namespace alib.