С GCC 4.8.2 (на 64-разрядных версиях Linux/Debian/Sid) -или GCC 4.9, если доступно - на С++ 11- У меня есть некоторый мьютекс
std::mutex gmtx;
фактически, это член static
в некотором классе Foo
, содержащий как методы alpha
, так и beta
ниже.
он заблокирован в alpha
как
void alpha(void) {
std::lock_guard<std::mutex> g(gmtx);
beta(void);
// some other work
}
и я хочу проверить beta
, что действительно gmtx
заблокировано:
void beta(void) {
assert (gmtx.is_locked());
// some real work
}
(заметим, что is_locked
вызывается только внутри assert
... Он может быть очень неэффективным или даже иногда неточным)
Конечно, у меня есть другие функции, вызывающие beta
, например.
void gamma(void) {
std::lock_guard<std::mutex> g(gmtx);
beta();
// some other work
}
но is_locked
не существует.... Как его определить? (на самом деле я хотел бы быть уверенным, что мьютекс заблокирован в том же потоке некоторым [косвенным] вызывающим абонентом...)
(причина, по которой я хочу проверить, что с assert
заключается в том, что beta
можно было бы назвать в другом месте)
Я не могу использовать try_lock
(если не использовать рекурсивные мьютексы), потому что в общем случае он блокирует уже заблокированный мьютекс... (заблокирован в том же потоке вызывающим), и это не только поведение undefined но полностью блокирует.
Я хочу избежать рекурсивных мьютексов (более дорогостоящих, чем обычные мьютексы), если мне действительно не нужно.
NB: реальная программа немного сложнее. Фактически, все методы находятся внутри класса, которые поддерживают двунаправленное отношение имен к "элементам". Поэтому у меня внутри класса есть карта от элементов к именам, а другая - от имен к элементам. beta
будет внутренним методом, добавляющим действительно именование, а alpha
и gamma
будут определять методы -или добавление элемента по его имени или имя по его элементу.
PS: реальная программа еще не выпущена, но должна стать частью MELT - ее будущее монитор; вы можете скачать его (альфа-сцена, очень багги) из здесь (временное местоположение)