How to assert if a std::mutex is locked?
c++, c++11, gcc, linux
Solution
`std::unique_lock<L>` has `owns_lock` member function (equivalent of `is_locked` as you say).
std::mutex gmtx;
std::unique_lock<std::mutex> glock(gmtx, std::defer_lock);
void alpha(void) {
std::lock_guard<decltype(glock)> g(glock);
beta(void);
// some other work
}
void beta(void) {
assert(glock.owns_lock()); // or just assert(glock);
// some real work
}
EDIT: In this solution, all lock operations should be performed via unique_lock `glock` not 'raw' mutex `gmtx`. For example, `alpha` member function is rewritten with `lock_guard<unique_lock<mutex>>` (or simply `lock_guard<decltype(glock)>`).
Problem
With GCC 4.8.2 (on Linux/Debian/Sid 64 bits) -or GCC 4.9 when available - in C++11- I have some mutex ``` std::mutex gmtx; ``` actually, it is a `static` member in some class `Foo` containing both `alpha` and `beta` methods below. it is locked in `alpha` like ``` void alpha(void) { std::lock_guard<std::mutex> g(gmtx); beta(void); // some other work } ``` and I want to check in `beta` that indeed `gmtx` is locked: ``` void beta(void) { assert (gmtx.is_locked()); // some real work } ``` (notice that `is_locked` is only called inside `assert`... It can be very inefficient or even sometimes inaccurate) Of course, I have other functions calling `beta`, e.g. ``` void gamma(void) { std::lock_guard<std::mutex> g(gmtx); beta(); // some other work } ``` but `is_locked` does not exist.... How should I define it? (actually I would like to be sure that the mutex has been locked in the same thread by some [indirect] caller...) (the reason I want to test that with `assert` is that `beta` could be called elsewhere) I cannot use `try_lock` (unless using recursive mutexes), because in the common case it would lock an already locked mutex... (locked in the same thread by a caller) and this is not only undefined behavior but blocks entirely. I want to avoid recursive mutexes (more costly than plain mutexes) unless I really have to. NB: The real program is a bit more complex. Actually, all the methods are inside a class which maintain a naming bi-directional relation on "items". So I have inside that class a map from items to names and another from names to items. `beta` would be the internal method adding really a naming, and `alpha` and `gamma` would be the methods finding -or adding- an item by its name, or a name by its item. PS: the real program is not yet released, but should become part of MELT - its future monitor; you can download it (alpha stage, very buggy) from here (a temporary location)