Implementing swap for class with std::mutex
You can use std::lock()
to acquire the locks in a non-deadlocking way.
If you want to use std::lock_guard
, have them adopt the locks once taken:
std::lock(lhs.mutex_, rhs.mutex_);std::lock_guard<std::mutex> lock_a(lhs.mutex_, std::adopt_lock);std::lock_guard<std::mutex> lock_b(rhs.mutex_, std::adopt_lock);//swap actionsswap(ls.str_, rhs.str_);
If you prefer std::unique_lock
, then construct them without locking, then call std::lock()
to lock them both (this also works with std::lock_guard
):
std::unique_lock<std::mutex> lock_a(lhs.mutex_, std::defer_lock);std::unique_lock<std::mutex> lock_b(rhs.mutex_, std::defer_lock);std::lock(lock_a, lock_b);//swap actionsswap(ls.str_, rhs.str_);
In both cases, you should first test for lhs
and rhs
being the same object, because using std::lock
with one mutex twice is undefined behavior:
if (&lhs == &rhs) return;
I don't think your swap implementation is safe. If another algorithm tries to lock rhs.mutex_
first and then lhs.mutex_
, you may end up with a deadlock. Try std::lock()
instead.