using RecursiveMutex = AnnotatedMixin<std::recursive_mutex>;
typedef AnnotatedMixin<std::mutex> Mutex;
Yes.
Pros:
* TODO: We should move away from using the recursive lock by default.
<sipa> recursive mutexes are evil
<sipa> there is probably a place for them, like goto
<sipa> but almost always, they just lead to badly designed abstractions
<sipa> a clear design should have code that operates outside the critical section, and code that operates inside
<sipa> but not code that works in both
- Anthony Williams (C++ Concurrency in Action, 2019, 3.3.3 Recursive locking):
Most of the time, if you think you want a recursive mutex, you probably need to change your design instead.
Cons: None.
The tracking issue: #19303.
Pros: see #1.
Cons:
... invasive refactors are hard to prioritize due to the conflicts they cause with non-refactoring changes.
... if removing RecursiveMutex makes the code/reasoning more complex, it's not a good idea.
the
RecursiveMutex
just works (TM).
Note 1. src/txmempool.h#L566-L569:
* To provide these guarantees, it is necessary to lock both `cs_main` and
* `mempool.cs` whenever adding transactions to the mempool and whenever
* changing the chain tip. It's necessary to keep both mutexes locked until
* the mempool is consistent with the new chain tip and fully populated.
Note 2. The goal is achievable, see: #19306.
If #2 gets project consensus, there are two approaches to untie some tangled knots in non-trivaial cases:
... move the lock up the stack if it prevents unnecessary unlocks/locks.
... two functions could be used - one that locks and another that does not...
If doing big refactors around
CTxMemPool::cs
, we may consider making it private.There is this from Clang documentation, which sounds perfectly reasonable to me: