Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 pass std::unique_lock<std::mutex> to lambda

I have some function which trying to lock std::mutex and if mutex successfully locked, function creates std::thread with lambda-function as thread function parameter, and also passes it lock using std::move():

static std::mutex mtx;
// some mutex defended stuff

void someFunc() {
    // try lock mutex using unique_lock
    std::unique_lock<std::mutex> lock(mtx, std::try_to_lock);
    if(!lock.owns_lock()) {
        return; // locking fails
    }

    // task for thread
    auto task = [&](std::unique_lock<std::mutex>&& lock) {
        // do async work and release lock when it done
        lock.unlock();

        // do something after releasing lock
    };

    // create thread, pass lock 
    std::thread taskThread(task, std::move(lock));
    taskThread.detach();
}

I've got compiler error:

<lambda_1918cc58d906c210588b1a8bb33f1b0d>::operator
()(std::unique_lock<_Mutex> &&) const' : cannot convert parameter 1 from
'std::unique_lock<_Mutex>' to 'std::unique_lock<_Mutex> &&'

How should I proper pass std::unique_lock to my lambda?

UPD: In fact this function is a native C API libaray call, it tryes to start some library operation async and returns control immediately in any case, returning some return code to caller. This code is simplified to concentrate on particaular issue.

like image 900
vard Avatar asked Feb 13 '23 05:02

vard


1 Answers

Your code compiles on both gcc and clang. It fails to compile on VS2013 (VC12) because of a bug in the implementation that requires the arguments to the std::thread constructor to be copyable. This results in the compiler attempting to copy the std::unique_lock, which, of course, fails.

However, your code has undefined behavior because you're locking and unlocking the mutex in two different threads, which is not allowed. The thread unlocking it must be the same as the one that had previously locked it.

like image 59
Praetorian Avatar answered Feb 15 '23 11:02

Praetorian