Boost logo

Boost :

From: williamkempf_at_[hidden]
Date: 2001-07-17 13:21:27


I responded once, but the response hasn't hit the list, so sorry if I
duplicate.

--- 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.

The following works, just to clarify what I said with code:

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

This is the only valid way to copy a "monitor", and making the mutex
copyable won't make the syntax any easier even if we can get safe
copy semantics.

> > >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?

When you copy a mutex as you've tried to do above it leads to
deadlock situations since the mutex state is now applied to two
distinct sets of data.
 
> Perhaps there is a way to work around the bad behavoir while keeping
> copyable.

If you can define a method that's safe, I'll reconsider the design.
However, this was fully discussed a year ago and everyone (yourself
included, if I recall correctly) agreed that copyable semantics were
wrong in this case.
 
> 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 specific case?

Bill Kempf


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