Skip to content

Commit 9703b7e

Browse files
committed
Merge bitcoin/bitcoin#32592: threading: remove ancient CRITICAL_SECTION macros
46ca771 threading: remove unused template instantiations (Cory Fields) b537a6a threading: remove obsolete critsect macros (Cory Fields) 0d0e0a3 threading: use a reverse lock rather than manual critsect macros (Cory Fields) 3ddd554 tests: Add Assertions in reverse_lock tests to exercise thread-safety annotations (Cory Fields) c88b1cb tests: get rid of remaining manual critsect usage (Cory Fields) Pull request description: Now that #32467 is merged, the only remaining usage of our old `CRITICAL_SECTION` macros (other than tests) is in `getblocktemplate()` and it can safely be replaced with a `REVERSE_LOCK`. This PR makes that replacement, replaces the old `CRITICAL_SECTION` macro usage in tests, then deletes the macros themselves. ~While testing this a few weeks ago, I noticed that `REVERSE_LOCK` does not currently work properly with our thread-safety annotations as after the `REVERSE_LOCK` is acquired, clang still believes that the mutex is locked. #32465 fixes this problem. Without that fix, this PR would potentially allow a false-negative if code were added in the future to this chunk of `getblocktemplate` which required `cs_main` to be locked.~ ~I added a test for the reverse lock here in the form of a compiler warning in `reverselock_tests.cpp` to simulate that possibility. This PR will therefore cause a new warning (and should fail a warnings-as-errors ci check) until #32465 is merged and this is rebased on top of it.~ Edit: Rebased on top of #32465, so this should now pass tests. ACKs for top commit: maflcko: review ACK 46ca771 📌 fjahr: Code review ACK 46ca771 TheCharlatan: ACK 46ca771 furszy: ACK 46ca771 Tree-SHA512: 5e423c8539ed5ddd784f5c3657bbd63be509d54942c25149f04e3764bcdf897bebf655553338d5af7b8c4f546fc1d4dd4176c2bce6f4683e76ae4bb91ba2ec80
2 parents 73220fc + 46ca771 commit 9703b7e

File tree

5 files changed

+18
-41
lines changed

5 files changed

+18
-41
lines changed

src/rpc/mining.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ static RPCHelpMan getblocktemplate()
704704
NodeContext& node = EnsureAnyNodeContext(request.context);
705705
ChainstateManager& chainman = EnsureChainman(node);
706706
Mining& miner = EnsureMining(node);
707-
LOCK(cs_main);
707+
WAIT_LOCK(cs_main, csmain_lock);
708708
uint256 tip{CHECK_NONFATAL(miner.getTip()).value().hash};
709709

710710
std::string strMode = "template";
@@ -810,8 +810,8 @@ static RPCHelpMan getblocktemplate()
810810
}
811811

812812
// Release lock while waiting
813-
LEAVE_CRITICAL_SECTION(cs_main);
814813
{
814+
REVERSE_LOCK(csmain_lock, cs_main);
815815
MillisecondsDouble checktxtime{std::chrono::minutes(1)};
816816
while (IsRPCRunning()) {
817817
// If hashWatchedChain is not a real block hash, this will
@@ -830,8 +830,6 @@ static RPCHelpMan getblocktemplate()
830830
checktxtime = std::chrono::seconds(10);
831831
}
832832
}
833-
ENTER_CRITICAL_SECTION(cs_main);
834-
835833
tip = CHECK_NONFATAL(miner.getTip()).value().hash;
836834

837835
if (!IsRPCRunning())

src/sync.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,6 @@ void EnterCritical(const char* pszName, const char* pszFile, int nLine, MutexTyp
206206
{
207207
push_lock(cs, CLockLocation(pszName, pszFile, nLine, fTry, util::ThreadGetInternalName()));
208208
}
209-
template void EnterCritical(const char*, const char*, int, Mutex*, bool);
210-
template void EnterCritical(const char*, const char*, int, RecursiveMutex*, bool);
211209
template void EnterCritical(const char*, const char*, int, std::mutex*, bool);
212210
template void EnterCritical(const char*, const char*, int, std::recursive_mutex*, bool);
213211

src/sync.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ LOCK2(mutex1, mutex2);
3939
4040
TRY_LOCK(mutex, name);
4141
std::unique_lock<std::recursive_mutex> name(mutex, std::try_to_lock_t);
42-
43-
ENTER_CRITICAL_SECTION(mutex); // no RAII
44-
mutex.lock();
45-
46-
LEAVE_CRITICAL_SECTION(mutex); // no RAII
47-
mutex.unlock();
4842
*/
4943

5044
///////////////////////////////
@@ -270,20 +264,6 @@ inline MutexType* MaybeCheckNotHeld(MutexType* m) LOCKS_EXCLUDED(m) LOCK_RETURNE
270264
#define TRY_LOCK(cs, name) UniqueLock name(LOCK_ARGS(cs), true)
271265
#define WAIT_LOCK(cs, name) UniqueLock name(LOCK_ARGS(cs))
272266

273-
#define ENTER_CRITICAL_SECTION(cs) \
274-
{ \
275-
EnterCritical(#cs, __FILE__, __LINE__, &cs); \
276-
(cs).lock(); \
277-
}
278-
279-
#define LEAVE_CRITICAL_SECTION(cs) \
280-
{ \
281-
std::string lockname; \
282-
CheckLastCritical((void*)(&cs), lockname, #cs, __FILE__, __LINE__); \
283-
(cs).unlock(); \
284-
LeaveCritical(); \
285-
}
286-
287267
//! Run code while locking a mutex.
288268
//!
289269
//! Examples:

src/test/reverselock_tests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ BOOST_AUTO_TEST_CASE(reverselock_basics)
1717
WAIT_LOCK(mutex, lock);
1818

1919
BOOST_CHECK(lock.owns_lock());
20+
AssertLockHeld(mutex);
2021
{
2122
REVERSE_LOCK(lock, mutex);
23+
AssertLockNotHeld(mutex);
2224
BOOST_CHECK(!lock.owns_lock());
2325
}
2426
BOOST_CHECK(lock.owns_lock());

src/test/sync_tests.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ void TestPotentialDeadLockDetected(MutexType& mutex1, MutexType& mutex2)
3737
template <typename MutexType>
3838
void TestDoubleLock2(MutexType& m)
3939
{
40-
ENTER_CRITICAL_SECTION(m);
41-
LEAVE_CRITICAL_SECTION(m);
40+
LOCK(m);
4241
}
4342

4443
template <typename MutexType>
@@ -48,31 +47,31 @@ void TestDoubleLock(bool should_throw)
4847
g_debug_lockorder_abort = false;
4948

5049
MutexType m;
51-
ENTER_CRITICAL_SECTION(m);
52-
if (should_throw) {
53-
BOOST_CHECK_EXCEPTION(TestDoubleLock2(m), std::logic_error,
50+
{
51+
LOCK(m);
52+
if (should_throw) {
53+
BOOST_CHECK_EXCEPTION(TestDoubleLock2(m), std::logic_error,
5454
HasReason("double lock detected"));
55-
} else {
56-
BOOST_CHECK_NO_THROW(TestDoubleLock2(m));
55+
} else {
56+
BOOST_CHECK_NO_THROW(TestDoubleLock2(m));
57+
}
5758
}
58-
LEAVE_CRITICAL_SECTION(m);
59-
6059
BOOST_CHECK(LockStackEmpty());
6160

6261
g_debug_lockorder_abort = prev;
6362
}
6463
#endif /* DEBUG_LOCKORDER */
6564

6665
template <typename MutexType>
67-
void TestInconsistentLockOrderDetected(MutexType& mutex1, MutexType& mutex2) NO_THREAD_SAFETY_ANALYSIS
66+
void TestInconsistentLockOrderDetected(MutexType& mutex1, MutexType& mutex2)
6867
{
69-
ENTER_CRITICAL_SECTION(mutex1);
70-
ENTER_CRITICAL_SECTION(mutex2);
68+
{
69+
WAIT_LOCK(mutex1, lock1);
70+
LOCK(mutex2);
7171
#ifdef DEBUG_LOCKORDER
72-
BOOST_CHECK_EXCEPTION(LEAVE_CRITICAL_SECTION(mutex1), std::logic_error, HasReason("mutex1 was not most recent critical section locked"));
72+
BOOST_CHECK_EXCEPTION(REVERSE_LOCK(lock1, mutex1), std::logic_error, HasReason("mutex1 was not most recent critical section locked"));
7373
#endif // DEBUG_LOCKORDER
74-
LEAVE_CRITICAL_SECTION(mutex2);
75-
LEAVE_CRITICAL_SECTION(mutex1);
74+
}
7675
BOOST_CHECK(LockStackEmpty());
7776
}
7877
} // namespace

0 commit comments

Comments
 (0)