
Hello all, I have been working on a project that uses the Boost Thread library, and I realized that there is a part of the code that needs to transfer a lock to a thread that has just been started. My idea for implementing this was to use a `boost::recursive_mutex` and pass a non-`const` reference to a `boost::recursive_mutex::scoped_lock` to the thread via `boost::ref`. Also, to ensure that the `scoped_lock` does not go out of scope until until the lock is moved, I thought to use a `boost::barrier`. After writing some test code, I find it interesting that if I use a `recursive_mutex`, then an assertion fails, but if I use a `boost::mutex`, then the code seems to work fine. Here is the test code that I have been experimenting with (the `recursive_mutex` version, which is also attached): #include <iostream> #include <boost/ref.hpp> #include <boost/thread.hpp> static boost::recursive_mutex s_mutex; static boost::barrier s_lockMoveBarrier(2); void thread_fun1(boost::recursive_mutex::scoped_lock& lock_) { //boost::recursive_mutex::scoped_lock testLock(s_mutex); // uncommenting this causes deadlock, as expected std::cout << "in `void thread_fun1(...)`: moving lock..."; boost::recursive_mutex::scoped_lock lock2(boost::move(lock_)); std::cout << "done" << std::endl; s_lockMoveBarrier.wait(); std::cout << "in `void thread_fun1(...)`: after the barrier" << std::endl; } int main() { boost::recursive_mutex::scoped_lock lock(s_mutex); std::cout << "in `int main()`: lock on `s_mutex` acquired" << std::endl; boost::thread(&thread_fun1, boost::ref(lock)); s_lockMoveBarrier.wait(); std::cout << "in `int main()`: after the barrier" << std::endl; } After compiling and running this on Debian Squeeze with Boost 1.42.0, I get: in `int main()`: lock on `s_mutex` acquired in `void thread_fun1(...)`: moving lock...done in `int main()`: after the barrier a.out: /usr/local/include/boost/thread/pthread/recursive_mutex.hpp:62: boost::recursive_mutex::~recursive_mutex(): Assertion `!pthread_mutex_destroy(&m)' failed. Aborted After replacing "boost::recursive_mutex" with "boost::mutex", however, the output is: in `int main()`: lock on `s_mutex` acquired in `void thread_fun1(...)`: moving lock...done in `void thread_fun1(...)`: after the barrier in `int main()`: after the barrier This leads me to wondering: 1. Is it correct and/or safe to move a lock to a new thread in this way? 2. Why does the `recursive_mutex` version fail and the `mutex` version succeed? Daniel Trebbien