|
Boost : |
Subject: [boost] [thread] Moving a `recursive_lock`
From: Daniel Trebbien (dtrebbien_at_[hidden])
Date: 2010-02-13 21:50:05
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk