Suppose I have code something like this:
#include "boost/thread/mutex.hpp"
using boost::mutex;
typedef mutex::scoped_lock lock;
mutex mut1, mut2;
void Func() {
// ...
}
void test_raiicomma_1() {
lock mut1_lock(mut1);
Func();
}
void test_raiicomma_2() {
(lock(mut1)), Func();
}
void test_raiicomma_3() {
(lock(mut1)), (lock(mut2)), Func(); // Warning!
}
int main()
{
test_raiicomma_1();
test_raiicomma_2();
test_raiicomma_3();
return 0;
}
If the function test_raiicomma_1
() were called from multiple threads, it locks a mutex to prevent any other thread also calling Func()
at the same time. The mutex is locked when the variable mut1_lock
is constructed, and released when it goes out of scope and is destructed.
This works perfectly fine, but as a matter of style, needing to give a name to the temporary object holding the lock irked me. The function test_raiicomma_2()
attempts to avoid this, by inialising the lock object and calling the function Func()
within one expression.
Is it correct that the temporary object destructor will not be called until the end of the expression, after Func()
has returned? (If so, do you think it's ever worthwhile to use this idiom, or is it always clearer to declare the lock in a separate statement?)
If the function test_raiicomma_3()
needs to lock two mutexes, is it correct that the mutexes will be locked in order before calling Func()
, and released afterwards, but may unfortunately be released in either order?