Boost logo

Boost :

From: williamkempf_at_[hidden]
Date: 2001-07-17 12:50:39


--- In boost_at_y..., Jeremy Siek <jsiek_at_r...> wrote:
> On Tue, 17 Jul 2001 williamkempf_at_h... wrote:
> > >
> > >class X {
> > > mutex* mtx;
> > > X() : mtx(new mutex()) { }
> > > ~X() { delete mtx; }
> > >};
> > >
> > >which is a pain.
> >
> > And simply wrong ;). A mutex *IS* a noncopyable concept. If you
> > remember, we discussed this early on in the design. Allowing a
mutex
> > to be copyable just leads to incorrect code, similar to what you
have
> > with your work around above. Why incorrect? Because the
> > implementation you have above results in two distinct sets of data
> > being protected by a single mutex. If CopyA locks the mutex then
> > CopyB is locked as well. This can lead to hard to diagnose
deadlocks.
>
> Actually, in the example above I had left out the copy constructor
for
> brevity, I did not mean to imply that the generated constructor
would be
> used.
>
> > However, just because the mutex isn't copyable doesn't mean that
an
> > object that contains a mutex must be noncopyable. It just means
you
> > can't rely on the compiler supplied copy c-tor and assignment
> > operator. This turns out to be a good thing any way, since such
> > operations should lock both mutexes before doing the copy, which
is
> > something the compiler supplied versions aren't going to do any
way.
>
> So you have to write a copy constructor like this:
>
> X(const X& x) : mtx(new mutex()), ... { }
>
> Which is also a pain.

Applying everything I said in response just to make things clear
through code:

class X {
public:
   mutable boost::mutex mtx;
   int a;
   X() : a(0) { }
   X(const X& other) : a(0) { boost::mutex::lock lock(other.mtx); a =
other.a; }
   ~X() { }
};

X x1;
X x2(x1);

This compiles, does what you want, is fairly trivial to code, and is
the only correct way to copy an object that uses the Monitor Pattern
(and this is true whether or not we allow mutexes to be copied). Note
that 'mtx' is mutable and is not copied in the user written copy c-
tor.

> > >So my question is this: is there any way we can get mutex to be
> > copyable?
> >
> > No. At least not while maintaining correct MT behavior. I'll add
> > this one to the FAQ as well, along with appropriate code examples
> > addressing both questions.
>
> So exactly what MT behaviour are you refering to?

Copying a mutex can only do a shallow copy, making both copies no
more than a reference to the same state. As illustrated by your own
example above this will lead to possible hard to find deadlocks and
over all confusion.

> Perhaps there is a way to work around the bad behavoir while keeping
> copyable.

I really doubt it, but if you prove me wrong we can re-evaluate the
design. Again, though, this was discussed at length a year ago and
everyone agreed on this point then (including yourself if I recollect
correctly).
 
> Cheers,
> Jeremy
>
> P.S. The reason I'm pushing on this is that the usage pattern I'm
looking
> at is a very common case, perhaps the most common case following
using a
> mutex in a simple scope.

And the code I gave above won't work for your usage pattern?

Bill Kempf


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk