Why does std :: lock_guard release the lock after using std :: accept_lock?

The following example invokes a method foo()where it acquires ownership of the mutex and blocks it. Then it calls check(), which acquires ownership, but assumes that the mutex is already locked and therefore simply uses it with the help std::adopt_lock.

But when it check()ends, the mutex unlocks. So when it foo()continues, the section that I tried to protect is actually no longer protected.

#include <mutex>
static std::mutex sessionLock;

bool check();

void foo() {
  std::lock_guard<std::mutex> guard(sessionLock);
  if (check()) {
    // Do transaction
    // Wait... the mutex is unlocked here!
  }
}

bool check() {
  std::lock_guard<std::mutex> guard(sessionLock, std::adopt_lock);
  // Critical section
  return true;
}

int main() {
  foo();
  return 0;
}

. - std::adopt_lock (.. lock()), unlock()? , , - , .

std::recursive_mutex, , std::mutex, check(), ?

+4
1

... , std::mutex, check(), , ?

. unique_lock<std::mutex> foo lock_guard const& unique_lock check, :

bool check(const std::unique_lock<std::mutex>& guard) {
  assert(guard.owns_lock());             // guard holds *some* mutex...
  assert(guard.mutex() == &sessionLock); // ...it is in fact sessionLock
  // Critical section
  return true;
}

void foo() {
  std::unique_lock<std::mutex> guard(sessionLock);
  if (check(guard)) {
    // Do transaction - guard is still locked.
  }
}
+1

Source: https://habr.com/ru/post/1619132/


All Articles