Strictement parlant, la question était de vérifier le verrouillage de std::mutex
directement. Cependant, si l'encapsuler dans une nouvelle classe est autorisé, c'est très simple :
class mutex :
public std::mutex
{
public:
#ifndef NDEBUG
void lock()
{
std::mutex::lock();
m_holder = std::this_thread::get_id();
}
#endif // #ifndef NDEBUG
#ifndef NDEBUG
void unlock()
{
m_holder = std::thread::id();
std::mutex::unlock();
}
#endif // #ifndef NDEBUG
#ifndef NDEBUG
/**
* @return true iff the mutex is locked by the caller of this method. */
bool locked_by_caller() const
{
return m_holder == std::this_thread::get_id();
}
#endif // #ifndef NDEBUG
private:
#ifndef NDEBUG
std::atomic<std::thread::id> m_holder;
#endif // #ifndef NDEBUG
};
Notez ce qui suit :
- En mode de publication, cela n'a aucune surcharge sur
std::mutex
sauf peut-être pour la construction/destruction (ce qui n'est pas un problème pour les objets mutex). - Le
m_holder
Le membre n'est accessible qu'entre la prise du mutex et sa libération. Ainsi, le mutex lui-même sert de mutex dem_holder
. Avec des hypothèses très faibles sur le typestd::thread::id
,locked_by_caller
fonctionnera correctement. - Autres composants STL, par exemple,
std::lock_guard
sont des modèles, ils fonctionnent donc bien avec cette nouvelle classe.
std::unique_lock<L>
a owns_lock
fonction membre (équivalent de is_locked
comme tu dis).
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
}
MODIF : Dans cette solution, toutes les opérations de verrouillage doivent être effectuées via unique_lock glock
non mutex "brut" gmtx
. Par exemple, alpha
la fonction membre est réécrite avec lock_guard<unique_lock<mutex>>
(ou simplement lock_guard<decltype(glock)>
).
Vous pouvez simplement utiliser un recursive_mutex
, qui peut être verrouillé plusieurs fois sur le même thread. Remarque :Si c'était mon code, je le restructurerais pour ne pas avoir besoin d'un recursive_mutex
, mais cela résoudra votre problème.