ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
smartlock.cpp
1// #################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2024 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
8
9#if !defined(ALIB_DOX)
10#if !defined(HPP_ALIB_THREADS_SMARTLOCK)
12#endif
13
14#if !defined (_GLIBCXX_ALGORITHM) && !defined(_ALGORITHM_)
15# include <algorithm>
16#endif
17#endif // !defined(ALIB_DOX)
18
19namespace alib { namespace threads {
20
22
24{
26 return static_cast<int>( acquirers.size() );
27}
28
30{
31 size_t count;
33 bool errAlreadyAdded= true;
34 int errWasAcquired= 0; )
35 {
37
38 count= acquirers.size();
39
40 // check doubly added
41 if ( newAcquirer == nullptr
42 || std::find( acquirers.begin(), acquirers.end(), newAcquirer ) == acquirers.end() )
43 {
45 errAlreadyAdded= false;
46 errWasAcquired= ThreadLock::CountAcquirements() != 0 ? 1 : 0; )
47
48 // switch on?
49 if( acquirers.size() == 1 )
50 {
51 ThreadLock* firstAcquirer= acquirers[0];
52
53 // non-anonymous acquirer?
54 if ( firstAcquirer != nullptr )
55 {
56 firstAcquirer->Acquire( ALIB_CALLER_PRUNED);
58 acquirers.emplace_back( newAcquirer );
59 ++count;
60 firstAcquirer->Release();
61 }
62
63 // critical section: our first acquirer is anonymous. As documented in class,
64 // this must happen only in situations, when we are sure, that we are safe, e.g. still
65 // single threaded execution of process bootstrap.
66 else
67 {
68 // If this assert happens, its only good luck: we detected a misuse. But it should
69 // be very seldom to be detected this way :-/
71 if ( errWasAcquired == 1 )
72 errWasAcquired= 2; )
73
75 acquirers.emplace_back( newAcquirer );
76 ++count;
77 }
78 }
79 else
80 acquirers.emplace_back( newAcquirer );
81 }
82 }// ALIB_LOCK_WITH
83
84
85 ALIB_ASSERT_ERROR( !errAlreadyAdded , "THREADS", "Acquirer already registered." )
86 ALIB_ASSERT_ERROR( errWasAcquired!=1, "THREADS", "Already acquired. Hint: Acquirer[0] must not acquire this before adding itself!" )
87 ALIB_ASSERT_ERROR( errWasAcquired!=2, "THREADS", "Acquired and acquirer[0] anonymous. Misuse of SmartLock!" )
88
89 return static_cast<int>( count );
90}
91
92int SmartLock::RemoveAcquirer( ThreadLock* acquirerToRemove )
93{
94 size_t count;
96 bool errWasAcquired;
97 bool errNotFound= true; )
98 {
100
101 ALIB_DBG(
102 errWasAcquired= ThreadLock::CountAcquirements() != 0; )
103
104 // search acquirer
105 auto it= std::find( acquirers.begin(), acquirers.end(), acquirerToRemove );
106 if( it != acquirers.end() )
107 {
108 ALIB_DBG(
109 errNotFound= false; )
110
111 // switch off?
112 if( acquirers.size() == 2 )
113 {
114 ThreadLock* acquirer1= acquirers[0];
115 ThreadLock* acquirer2= acquirers[1];
116 if( acquirer1== acquirerToRemove ) acquirer1= nullptr;
117 if( acquirer2== acquirerToRemove ) acquirer2= nullptr;
118
119 // Acquire acquirers in their order of appearance
120 if ( acquirer1 != nullptr ) acquirer1->Acquire(ALIB_CALLER_PRUNED);
121 if ( acquirer2 != nullptr ) acquirer2->Acquire(ALIB_CALLER_PRUNED);
123 acquirers.erase( it );
124 if ( acquirer2 != nullptr ) acquirer2->Release();
125 if ( acquirer1 != nullptr ) acquirer1->Release();
126 }
127
128 // just remove acquirer, keep mode
129 else
130 acquirers.erase( it );
131 }
132 count= acquirers.size();
133 }
134
135 ALIB_ASSERT_ERROR( !errNotFound, "THREADS", "Acquirer not found." )
136 ALIB_ASSERT_ERROR( !errWasAcquired, "THREADS", "Acquired on release. Hint: Acquirers must acquire only when acquired themselves!" )
137 return static_cast<int>( count );
138}
139
140}} // namespace [alib::threads]
ALIB_API int RemoveAcquirer(ThreadLock *acquirer)
Definition smartlock.cpp:92
std::vector< ThreadLock * > acquirers
Definition smartlock.hpp:58
ALIB_API int CntAcquirers()
Definition smartlock.cpp:23
ALIB_API int AddAcquirer(ThreadLock *newAcquirer)
Definition smartlock.cpp:29
static ALIB_API SmartLock StdOutputStreams
ALIB_API void Acquire(const NCString &dbgFile, int dbgLine, const NCString &dbgFunc)
ALIB_API void SetSafeness(lang::Safeness safeness)
ALIB_API void Release()
defined(ALIB_DOX)
#define ALIB_ASSERT_ERROR(cond,...)
Definition alib.hpp:984
#define ALIB_DBG(...)
Definition alib.hpp:457
#define ALIB_CALLER_PRUNED
Definition alib.hpp:845
#define ALIB_LOCK_WITH(lock)
@ Safe
Do it or treat it with safety.
@ Unsafe
Omit checks or perform unsafe operations.
Definition alib.cpp:57
threads::SmartLock SmartLock
Type alias in namespace alib.