4#include "Stroika/Foundation/StroikaPreComp.h"
16using namespace Stroika::Foundation::Debug;
18#if qStroika_Foundation_Debug_AssertExternallySynchronizedMutex_Enabled
24void AssertExternallySynchronizedMutex::lock_ () noexcept
27 SharedContext* sharedContext = fSharedContext_.get ();
28 if (sharedContext->fFullLocks_++ == 0) {
30 sharedContext->fThreadWithFullLock_ = this_thread::get_id ();
31 if (not sharedContext->GetSharedLockEmpty_ ()) {
33 Require (sharedContext->CountOfIInSharedLockThreads_ (sharedContext->fThreadWithFullLock_) ==
34 sharedContext->GetSharedLockThreadsCount_ ());
39 if (sharedContext->fThreadWithFullLock_ != this_thread::get_id ()) {
43#if !qCompilerAndStdLib_FormatThreadId_Buggy
44 DbgTrace (
"ATTEMPT TO modify (lock for write) an object which is already in use (debuglocked) in another thread (thisthread={})"_f,
45 this_thread::get_id ());
46 DbgTrace (
"Original thread holding lock: threadID={}, and DbgTraceThreadName={}"_f,
51 Require (sharedContext->fThreadWithFullLock_ == this_thread::get_id ());
59bool AssertExternallySynchronizedMutex::try_lock_ () noexcept
62 bool lockedSuccessfully =
true;
64 SharedContext* sharedContext = fSharedContext_.get ();
65 if (sharedContext->fFullLocks_++ == 0) {
67 sharedContext->fThreadWithFullLock_ = this_thread::get_id ();
68 if (not sharedContext->GetSharedLockEmpty_ ()) {
70 lockedSuccessfully = sharedContext->CountOfIInSharedLockThreads_ (sharedContext->fThreadWithFullLock_) ==
71 sharedContext->GetSharedLockThreadsCount_ ();
76 lockedSuccessfully = (sharedContext->fThreadWithFullLock_ == this_thread::get_id ());
78 if (not lockedSuccessfully) {
84 lockedSuccessfully =
false;
86 return lockedSuccessfully;
89void AssertExternallySynchronizedMutex::unlock_ () noexcept
91 SharedContext* sharedContext = fSharedContext_.get ();
92 Require (sharedContext->fThreadWithFullLock_ == this_thread::get_id ());
93 Require (sharedContext->fFullLocks_ > 0);
94 --sharedContext->fFullLocks_;
99void AssertExternallySynchronizedMutex::lock_shared_ () const noexcept
102 SharedContext* sharedContext = fSharedContext_.get ();
105 if (sharedContext->fFullLocks_ != 0) {
107 if (sharedContext->fThreadWithFullLock_ != this_thread::get_id ()) {
111 DbgTrace (
"ATTEMPT TO shared_lock (lock for READ) an object which is already in use (debuglocked for WRITE) in another thread"_f);
112 DbgTrace (
"Original thread holding (write) lock: threadID={}, and DbgTraceThreadName={}"_f,
113 Characters::ToString (Execution::Thread::FormatThreadID_A (sharedContext->fThreadWithFullLock_)),
116 Require (sharedContext->fThreadWithFullLock_ == this_thread::get_id ());
118 sharedContext->AddSharedLock_ (this_thread::get_id ());
125void AssertExternallySynchronizedMutex::unlock_shared_ () const noexcept
128 SharedContext* sharedContext = fSharedContext_.get ();
129 sharedContext->RemoveSharedLock_ (this_thread::get_id ());
136mutex& AssertExternallySynchronizedMutex::GetSharedLockMutexThreads_ ()
138 static mutex sMutex_;
#define AssertNotReached()
String ToString(T &&t, ARGS... args)
Return a debug-friendly, display version of the argument: not guaranteed parsable or usable except fo...
wstring FormatThreadID(Thread::IDType threadID, const FormatThreadInfo &formatInfo={})