4#include "Stroika/Foundation/StroikaPreComp.h"
16using namespace Stroika::Foundation::Debug;
18#if qStroika_Foundation_Debug_AssertExternallySynchronizedChecker_Enabled
24void AssertExternallySynchronizedChecker::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 DbgTrace (
"ATTEMPT TO modify (lock for write) an object which is already in use (debuglocked) in another thread (thisthread={})"_f,
44 this_thread::get_id ());
45 DbgTrace (
"Original thread holding lock: threadID={}, and DbgTraceThreadName={}"_f,
49 Require (sharedContext->fThreadWithFullLock_ == this_thread::get_id ());
57bool AssertExternallySynchronizedChecker::try_lock_ () noexcept
60 bool lockedSuccessfully =
true;
62 SharedContext* sharedContext = fSharedContext_.get ();
63 if (sharedContext->fFullLocks_++ == 0) {
65 sharedContext->fThreadWithFullLock_ = this_thread::get_id ();
66 if (not sharedContext->GetSharedLockEmpty_ ()) {
68 lockedSuccessfully = sharedContext->CountOfIInSharedLockThreads_ (sharedContext->fThreadWithFullLock_) ==
69 sharedContext->GetSharedLockThreadsCount_ ();
74 lockedSuccessfully = (sharedContext->fThreadWithFullLock_ == this_thread::get_id ());
76 if (not lockedSuccessfully) {
82 lockedSuccessfully =
false;
84 return lockedSuccessfully;
87void AssertExternallySynchronizedChecker::unlock_ () noexcept
89 SharedContext* sharedContext = fSharedContext_.get ();
90 Require (sharedContext->fThreadWithFullLock_ == this_thread::get_id ());
91 Require (sharedContext->fFullLocks_ > 0);
92 --sharedContext->fFullLocks_;
97void AssertExternallySynchronizedChecker::lock_shared_ () const noexcept
100 SharedContext* sharedContext = fSharedContext_.get ();
103 if (sharedContext->fFullLocks_ != 0) {
105 if (sharedContext->fThreadWithFullLock_ != this_thread::get_id ()) {
109 DbgTrace (
"ATTEMPT TO shared_lock (lock for READ) an object which is already in use (debuglocked for WRITE) in another thread"_f);
110 DbgTrace (
"Original thread holding (write) lock: threadID={}, and DbgTraceThreadName={}"_f,
111 Characters::ToString (Execution::Thread::FormatThreadID_A (sharedContext->fThreadWithFullLock_)),
114 Require (sharedContext->fThreadWithFullLock_ == this_thread::get_id ());
116 sharedContext->AddSharedLock_ (this_thread::get_id ());
123void AssertExternallySynchronizedChecker::unlock_shared_ () const noexcept
126 SharedContext* sharedContext = fSharedContext_.get ();
127 sharedContext->RemoveSharedLock_ (this_thread::get_id ());
134mutex& AssertExternallySynchronizedChecker::GetSharedLockMutexThreads_ ()
136 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={})