From: William Kempf (sirwillard_at_[hidden])
Date: 2000-09-14 10:15:42
--- In boost_at_[hidden], Csaba Szepesvari <szepes_at_m...> wrote:
> Levente Farkas wrote:
> > hi,
> > I find an example where lock and unlock can be useful.
> [You're going to think that Hungarian (Mindmaker) people have
teamed up in this
> subject;) Anyway, I feel I have to say something. Hope that it will
> I agree with Levente on that having a lock() exposed would be
useful (as shown by
> the example he provided).
> However, having a lock on the mutex is probably not the best way
> exception safety considerations as people have already noted here.
> However, having another lock class, say `alock' [not a very good
name, I know ;-) -
> we could also use templates with different parameters and having
only one lock
> class] with an explicit lock function, but with one that would
count the calls to
> lock() itself and in the destructor unlocking the mutex the
appropriate number of
> times - this class would resolve *some* of the safety
considerations raised here
> So Levente's example would look like:
> boost::alock lock(m); // this already locks m
> for (int i = a.get(); i < 10; a.next())
> <some code part 1>
> <some code part 2>
> // lock's destructor releases the mutex m the app. no. of times
> and if an exception is thrown in <some code part 1> or <some code
part 2> then the
> lock unlocks m the appropriate number of times.
I've already addressed this throroughyly, so I'll keep my comments
minimal this time. For more info, check the list archive.
You do not want the lock to do recursive locking. This is a trait of
the mutex, not the lock. This interface is also less safe, since it
removes any hope for compile time checking of the lock status in
calls such as condition::wait(). I did, however, provide just such a
lock called unsafe_lock<> that used the currently available interface
to achieve this! So you really are unlikely to convince me here.
> Ok, you can try to call unlock more no. of times that you called
lock - but is not
> this the same with `delete'?? Life is dangerous.. .. or do not use
C++ ;) Maybe,
> unlock should not do anything when called a larger number of times
than lock? I
> guess I would not like this I don't know why, just a feeling - I
prefer throwing an
> exception (it will turn out soon - hopefully- that there is a
problem with the code)
Using C++ doesn't have to be dangerous. This particular problem can
be easily worked around. The best way to work around it is to not
allow recursive locks like this. Instead, you allow recursive
> Also, having two different types, one with lock() exposed, another
one without it,
> and having condition only accept the one without the lock() method
exposed - the
> compile time guarantee needed for condition::wait() would be ok,
That's precisely what unsafe_lock<> does, and it does it using the
existing interface. I don't have strong objections to including
unsafe_lock<> in the library, provided the name indicates that it's
less safe and it's not exposed as a direct part of the Mutex
concept. These qualities reduce the likelyhood that the lock will be
abused by ignorant or careless programmers.
> As to the deadlocks, you can cause deadlocks easily even using
> the textbook example:
I never claimed that we eliminated all dead locks with this
interface. I claimed we reduced the likelyhood, which I believe we
have. At some point we'll need to consider ways to detect and
possibly prevent deadlocks such as the one you show here. I just
don't care to focus on this issue right now, since it'll have minimal
impact to the concepts (if any). Right now we're focusing on
defining the concepts.
> Having the two types of locks differing only in a template
parameter and letting the
> default be the one that disables the lock() method would also mean
that people would
> use the one exposing lock() only when they really need that one.
That's what I said when I posted the unsafe_lock<> ;).
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk