Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can std::recursive_mutex be used reliably?

The cppreference page for std::recursive_mutex says:

The maximum number of times that a recursive_mutex may be locked is unspecified, but after that number is reached, calls to lock will throw std::system_error and calls to try_lock will return false.

So:

  • If I take this literally, I have to conclude that it's unsafe to use (lock) a std::recursive_mutex at all, since that maximum may be zero.

  • But, maybe that interpretation is too silly, and I should assume it means the maximum is always at least 1, and may be exactly 1? Ok, in that case, it's safe to use std::recursive_mutex like std::mutex, but it's unsafe to ever use it recursively (i.e. lock it twice simultaneously), since the maximum may be 1.

  • But, maybe that interpretation is still too silly, and I should assume it means the maximum is always at least 2, and may be exactly 2? Ok, in that case I can lock it twice, but it's unsafe to lock it 3 times.

The reasoning above seems increasingly tenous, which seems to lead to the conclusion "std::recursive_mutex doesn't have a clear contract, so it's unsafe to use it, period". I.e. if I want a reliable recursive mutex, I have to write my own.

(Attempting to handle the std::system_error doesn't seem like a realistic alternative, since it would be simpler to just write an alternative recursive mutex implementation from scratch, and not use std::recursive_mutex at all.)

This seems a shame, since std::recursive_mutex might, in reality, be a high-quality implementation whose maximum is hundreds, or thousands, or billions (maybe 231-1), or quintillions (maybe 263-1), any of which would be useful if it could be relied on.

Is there any safe/reliable way to use std::recursive_mutex ?

like image 936
Don Hatch Avatar asked Jan 30 '26 03:01

Don Hatch


1 Answers

The standard does not specify the number, but I think it is reasonable to assume that it is a reasonable number.

For 32 bits processors I would expect it to be a 32 bit recursion (approx 4Billion) - that would not be achievable, as the stack used by 4 billion calls would consume all the memory of the processor.

For 64 bit machines, either 32 or 64 bits would be reasonable.

Algorithmically the recursive use of a mutex is problematic - if you think the potential recursions are > the number of bits on the processor (32 recursions / 64 recursions), then you probably need an alternative design - where the lock is held more globally and not used in inner functions.

The unspecified nature, allows the standard to be flexible, yet deliver something useful. If they specified a minimum size, that may limit the ability to implement C++ on some processors, due to the counter would need to be some form of atomic operation to work successfully.

like image 156
mksteve Avatar answered Feb 01 '26 19:02

mksteve