
Howard Hinnant wrote:
On Mar 22, 2007, at 3:20 PM, Yuval Ronen wrote:
The main thing I was thinking about is the move constructor. Instead of stealing the mutex from the rvalue, you construct a new mutex, and let the old one be destructed. This might be not optimal. But on the other hand, it might not be that bad after all, I don't know...
<nod> If it did turn up a red flag in the profiling of A, then perhaps A could be changed to:
class A { int* the_data_; std::unique_ptr<std::sharable_mutex> mut_; ...
With an invariant that if the_data_ is non-null then so is mut_, otherwise both are null.
This would probably (I haven't fully analyzed it) be no more inefficient than if we did this:
class mutex { pthread_mutex_t* mut_; // on heap ...
And it enables other clients of mutex to not have to pay for a heap allocation internal to std::mutex if their app didn't need it.
I agree.
Hmm... and if your std::mutex ctor can throw an exception (in general it can), the A design with a plain mutex has a throwing move constructor which can be bad if you want to vector<A>. The A design with the mutex* side steps that problem I believe.
So the general recommendation for a class that holds a mutex and should be movable is to dynamically allocate the mutex. Pity, but maybe inevitable. <fantasy> Unless POSIX would change to allow movable pthread_mutex_t... </fantasy>