Reputation: 2272
Please help me check if my understanding of std::unique_lock
move semantic is correct.
Let's say I have a function myFunc
which needs to acquire a mutex at the beginning of its execution.
This function is called from different functions, some of them e.g. myWrapper1
hold the same mutex before myFunc
call.
Sometimes I need this lock not be released when myFunc
's scope exits.
typedef std::unique_lock<std::mutex> MyLock;
class Example2
{
std::mutex m_data_mutex;
MyLock&& myFunc(MyLock&& lk)
{
bool was_lock = lk.owns_lock();
if( !was_lock ) lk.lock();
std::cout << "myFunc" << std::endl;
if( !was_lock ) lk.unlock();
return std::move(lk);
}
void myWrapper1()
{
MyLock lk(m_data_mutex);
std::cout << "1" << std::endl;
lk = myFunc(std::move(lk));
std::cout << "2" << std::endl;
}
void myWrapper2()
{
MyLock lk(m_data_mutex);
std::cout << "1" << std::endl;
lk.unlock();
lk = myFunc(std::move(lk));
std::cout << "2" << std::endl;
lk.lock();
std::cout << "3" << std::endl;
}
};
So the questions are:
myWrapper1
there's a guarantee that MyLock
will be released only at the end of myWrapper1
scope, isn't it?Upvotes: 2
Views: 1017
Reputation: 27190
Is there some reason why you can't do something like this instead? IMO, it's a lot more clean than moving locks around from owner to owner.
std::mutex my_lock;
void myFunc_locked() {
...do something that requires my_lock to be locked...
}
void myFunc() {
std::lock_guard<std::mutex> guard(my_lock);
myFunc_locked();
}
void myWrapper1() {
std::lock_guard<std::mutex> guard(my_lock);
...do something else that requires my_lock to be locked...
myFunc_locked();
}
void myWrapper2() {
...
myFunc();
}
Or, do as @Nevin suggested. Maybe cleaner still:
std::mutex my_lock;
void myFunc(std::lock_guard<std::mutex>> const& guard) {
...do something that requires my_lock to be locked...
}
void myFunc() {
std::lock_guard<std::mutex> guard(my_lock);
myFunc(guard);
}
void myWrapper1() {
std::lock_guard<std::mutex> guard(my_lock);
...do something else that requires my_lock to be locked...
myFunc(guard);
}
void myWrapper2() {
...
myFunc();
}
Upvotes: 2