I have a QList of MyClass. Appending and deleting items from list are rare and cotrolled by common list mutex. MyClass contains several substructures and personal QReadWriteLock:
MyClass{
private:
Substructure substructure;
QReadWriteLock rwlElem;
}
I put lockers in accesors like that:
Substructure MyClass::getSub(){
QReadLocker lock(&rwlElem);
return substructure;
}
I expect that copy of substructure will be safely returned. Same things I made in setters. Is this good practice to use lockers like that? What happens first: copy construction of the substructure or destruction of the locker?
I'll start by answering your last question:
TL;DR: copy construction happens before destruction of all local variables.
This has been asked several times here on stackoverflow, see here, here and here.
More precise wording has been applied to the C++14 standard by CWG 1885:
Having two mutexes to lock can make you prone to deadlocks. However you can avoid that by following one of these two guidelines:
MyClass
instance's read/write mutex when you need both to lock both mutexes).Assuming you used
QWriteLocker
in your setters, this should be okay (in the sense that it does not cause undefined behavior). But you have to pay attention to what your interface is really saying. For example when you are doing something like this to an instancemc
of typeMyClass
:By the time the thread executing the above code gets to compare
s
withanotherSubstructure
, another thread might change the actualsubstructure
insidemc
, and this change isn't visible to the former thread (since it gets its own copy of thesubstructure
).The point is, when you do
Substructure s = mc.getSub();
, the only thing you get to know is thatmc
's substructure was equal tos
at some point in time, and this value might change as soon as you released the lock in yourgetSub
function.In my above example,
doSomething()
cannot assume that the value ofmc
's substructure is still equal toanotherSubstructure
. You may need to group operations that need to be atomic in their own functions (with locks properly assuring that the values don't change in a case like the above).