10#if !defined (HPP_ALIB_THREADS_THREADLOCK)
14#if !defined (HPP_ALIB_THREADS_DETAIL_THREADMAP)
18#if !defined (HPP_ALIB_STRINGS_LOCALSTRING)
23namespace alib {
namespace threads {
26: owner(std::thread::id())
50 && DbgRecursionWarningThreshold != 0
51 && (cntAcquirements % DbgRecursionWarningThreshold) != 0,
52 "THREADS",
"Recursion depth warning.\n"
53 "To prevent this, change ThreadLock.recursionWarningThreshold or fix your code.\n"
54 "Depth: ", cntAcquirements )
60 auto thisThreadID= std::this_thread::get_id();
63 if( thisThreadID == owner )
70 && DbgRecursionWarningThreshold != 0
71 && (cntAcquirements % DbgRecursionWarningThreshold) != 0,
72 "THREADS",
"Recursion depth warning.\n"
73 "To prevent this, change ThreadLock.recursionWarningThreshold or fix your code.\n"
74 "Depth: ", cntAcquirements )
81 bool hasWarned=
false;
82 std::chrono::steady_clock::time_point waitTime= std::chrono::steady_clock::now();
86 {std::unique_lock<std::mutex> lock(mutex);
89 while( owner != std::thread::id() )
93 if( DbgWarningAfterWaitTimeInMillis <= 0 || hasWarned )
96 mutexNotifier.wait( lock );
103 mutexNotifier.wait_for( lock, std::chrono::milliseconds(DbgWarningAfterWaitTimeInMillis) );
105 auto milliseconds= std::chrono::duration_cast<std::chrono::milliseconds>(
106 std::chrono::steady_clock::now() - waitTime ).count();
108 if ( milliseconds >= DbgWarningAfterWaitTimeInMillis )
111 auto actualOwner= owner;
118 <<
"Waiting on ThreadLock since " << milliseconds <<
" ms. Reasons might be "
119 "a dead lock, an non-optimized critical section\n"
120 "or simply too much load on the executing machine. More Info:"
121 <<
"\n Owner : " << ownerThread->GetId() <<
'/' << ownerThread->GetName()
122 <<
" at: " << DbgOwnerFile <<
':' << DbgOwnerLine <<
" " << DbgOwnerFunc <<
"()."
123 <<
"\n This thread : " << thisThread ->GetId() <<
'/' << thisThread ->GetName()
124 <<
" at: " << dbgFile <<
':' << dbgLine <<
" " << dbgFunc <<
"()."
137 DbgOwnerFile= dbgFile;
138 DbgOwnerLine= dbgLine;
139 DbgOwnerFunc= dbgFunc;
155 ALIB_ERROR(
"THREADS",
"Release without acquire (unsafe mode)."
156 "Note: This must never happen, check your code, set lock to safe mode!" )
168 std::unique_lock<std::mutex> lock(
mutex);
179 owner= std::thread::id();
194 ALIB_ERROR(
"THREADS",
"Cannot switch safeness mode while already locked.\n"
195 " Current mode: unsafe, requested mode: ",
208 std::unique_lock<std::mutex> lock(
mutex);
211 if (
owner != std::thread::id() )
216 "Cannot switch safeness mode while already locked.\n"
217 " Current mode: safe, requested mode: " <<
220 " Owner: " << ownerThread->GetId() <<
'/' << ownerThread->GetName() )
Thread * GetOwner() const
ALIB_API void Acquire(const NCString &dbgFile, int dbgLine, const NCString &dbgFunc)
ALIB_API ThreadLock(lang::Safeness safeness=lang::Safeness::Safe)
ALIB_API void SetSafeness(lang::Safeness safeness)
lang::Safeness GetSafeness() const
ALIB_API void Release()
defined(ALIB_DOX)
std::condition_variable mutexNotifier
static Thread * GetCurrent()
#define ALIB_WARNING(...)
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_ASSERT_WARNING(cond,...)
#define ALIB_REL_DBG(releaseCode,...)
@ Safe
Do it or treat it with safety.
@ Unsafe
Omit checks or perform unsafe operations.
ALIB_API Thread * getThread(std::thread::id c11ID)
threads::Thread Thread
Type alias in namespace alib.
NLocalString< 256 > NString256
Type alias name for TLocalString<nchar,256> .
NLocalString< 1024 > NString1K
Type alias name for TLocalString<nchar,1024> .