Boost logo

Boost :

From: William E. Kempf (williamkempf_at_[hidden])
Date: 2002-05-17 11:25:14


----- Original Message -----
From: "Mattias Flodin" <flodin_at_[hidden]>

> On Fri, May 17, 2002 at 08:58:07AM -0500, William E. Kempf wrote:
> > You know the precise lifetime with an auto_ptr. This is clearly
controlled
> > by the "single ownership" and "transfer of control" semantics specified
by
> > the standard. You can "extend" the lifetime outside of the initial
"scope"
> > (sorry to keep using quotes, but I'm not quite using the terminology
100%
> > technically accurate) by using the move semantics to transfer ownership
to a
> > new instance, but the lifetime is still clearly delineated in this case.
So
> > I'm not sure I see a difference that will cause more problems for a
> > ScopedLock with move semantics based on the need to know the exact
lifetime.
>
> I suppose the problem is when people start using it in bad ways, i.e.
> not just for the kind of proxy you described but for passing locks
> around into and out of functions in various ways.

This doesn't cause you to not know the exact lifetime of the lock... it just
means the programmer had better understand the rules of move semantics. In
other words, as long as you pay attention to how move semantics work this is
a very deterministic mechanism for lock management, as opposed to say how
shared_ptr works.

> Not that this in
> itself is bad, but you can end up in situations where you lose the
> lock even if you didn't expect to (by passing the lock into a function
> and assuming you still have it when the function returns), which
> could cause several threads to simultaneously run critical code.

If you know the rules of move semantics this isn't a case where you'd lose
the lock but didn't expect to. The problem is, as with auto_ptr, newbies
don't understand the rules of move semantics so *they* are surprised. So,
yes, I agree this is a major drawback to this solution, and that's precisely
why I asked for RFC on it. Are the dangers worse then the dangers present
with exposed lock/unlock methods? What if the move semantics used syntax
that made it more appearant what was going on (such as the proxy suggestion
I made in another reply) to reduce surprise for newbies?

> Or
> situations where the lock is held longer than you wanted (e.g. when a
> returned lock is saved on the local stack). Yes, these are stupid
> things to do, but so is locking a mutex and forgetting to unlock it.
>
> I would be inclined to agree with earlier postings that a "raw"
> interface is needed, upon which more sophisticated structures can be
> built. Even move semantics may not be sufficient for all needs (or do
> you always use auto_ptr for managing your memory?).

The two concepts can't be totally compared in this way. While auto_ptr
obviously doesn't always meet my memory management needs a ScopedLock with
move semantics may meet all of my lock management needs. For instance, as
I've pointed out elsewhere, shared locks would be a bad idea with probably
no valid use case while shared pointers are common. However, this is still
one of the important questions to be answered... would a ScopedLock with
move semantics cover all use cases sufficiently?

> This comes down to
> a question whether we really want to prevent everyone from making
> errors, at the cost of preventing everyone from building their own
> customized ownership handlers. After all, boost is partly meant to be
> a building block for library programmers.

Well, one point to be made is that even given the current design for
ScopedLocks there's nothing that can't be accomplished (at least that I've
seen so far). The crux of the problem isn't whether something can be done,
it's whether it can be done efficiently. Locks that cross scope boundaries
are common enough that an efficient solution is needed, and the current
design doesn't allow one. With move semantics it might cover enough of the
use cases (all of them?) that there's little need for covering the remaining
ones. I don't know... that's what I'm trying to explore with this thread.

> Do you really believe that such unsafe primitives would be favored for
> general (non-library-internals) usage by the majority? Personally,
> when I choose what to use in a library and how to use it, I value
> things that help me avoid my own mistakes - but only to the point that
> I can use them in the way I need to. Something that is safe but
> doesn't do what I need isn't going to help me. If the library doesn't
> provide that lower level as a 'fallback', I will have to look for
> other libraries. To assume someone will make mistakes is an insult; to
> provide him with means to avoid them is a favor.

I generally agree, but it depends on how dangerous and how frequently
mistakes are made as to whether or not an interface should be included
(assuming the "unsafe" interface is not the only solution to some set of
problems). I don't want to prevent solutions for anything by choosing
"safe" interfaces, but if possible I want to provide the safest possible
interface(s) that will cover all use cases. That's what I'm exploring.

Bill Kempf


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