|
Boost : |
From: William Kempf (sirwillard_at_[hidden])
Date: 2000-09-14 16:38:43
--- In boost_at_[hidden], Eric Swanson <ESwanson_at_I...> wrote:
> > -----Original Message-----
> > From: William Kempf [mailto:sirwillard_at_m...]
> > There's reasons to prefer this over your suggestion, which I'll
get
> > to later. The point I'd make here, though, is that this is an
> > implementation detail of unsafe_lock<>. This means several
things.
> > For one, the fact that placement new is "icky" is irrelevant
here,
> > since it's buried in the implementation. For another, this means
> > that a different implementation of the same interface may very
well
> > not use placement new (in fact, your example is just such an
> > alternate implementation). In other words, since we're
discussing
> > prototypes here the implementation details are mostly off-topic
at
> > this stage. They are only on-topic as the discussion pertains to
> > possible need for modification of the concepts. My
implementation,
> > whether you like placement new or not, is proof that a
modification
> > of the concepts is not needed or warranted.
>
> My example can only be implemented if mutex<> knows about it. It's
not
> merely an implementation detail if your implementation disallows
extension.
> Your implementation assumes that you know about every type of
useful lock,
> and that any other type of lock must be implemented in terms of
> construction/destruction of your locks.
a) The implementation must know about the locks. This is the
purpose in nesting them. I've used templates for the locks in my
implementation to simplify coding, but this is not a requirement of
any implementations, and extended Mutex types are likely to use very
different implementations.
b) unsafe_lock<> is a special beast. It allows non-scoped
locking/unlocking for rare corner cases. It's specifically designed
to work with any implementation provided it follows the (minimal)
interface defined for the concept.
c) As long as we have unsafe_lock<> you can use it to define any
other exotic locks you want to. With out it, you can use the same
techniques employeed by it for these other locks.
In other words, the interface is minimal but complete. Lock/unlock
functionality is exposed, just not in the manner that some may like
for certain cases, but to my mind that doesn't warrant modification
of the interface.
> > I really don't understand why the STL did this. stack<> is not
> > designed for polymorphic behavior (no virtual d-tor) so the only
> > benefit this safely buys is the ability to access the container
in
> > protected/private derivation. I don't see how this could apply
to
> > our current discussion.
>
> I mentioned it as an example of an inclusive, or humble,
interface. It
> allows the programmer access if needed, but discourages misuse
through
> protected access. It doesn't assume that the library designers
have thought
> of every possible use. It also shows a precedent in the STL for
allowing
> more access through derivation.
It doesn't apply here, though.
> > Don't think in terms of implementation. Think in generic terms
of
> > the concepts. This means that (a) isn't really an option. Every
> > concrete implementation of the Mutex concept will have to have a
> > corresponding implementation (specialization?) of unsafe_lock<>.
> > Meanwhile, (b) is proof that a generic implementation of
> > unsafe_lock<> can be built solely using the Concept, with no
reliance
> > on any implementation details.
>
> It's relying on the interface. The only interface provided is
> construction/destruction. Just because unsafe_lock<> can be
implemented
> with the existing interface doesn't mean that the interface is
adequate.
How is it inadequate?
> > A mutex_accessor<> would simplify development of various lock
types,
> > but it would also expose the very methods that are so dangerous
on a
> > mutex to begin with. You might as well expose those methods
directly
> > on the mutex.
>
> Not necessarily. I was thinking of something like this:
>
> template <typename M>
> class mutex_accessor
> {
> private:
> mutex_accessor(const mutex_accessor&);
> operator=(const mutex_accessor);
>
> protected:
> mutex_accessor(M& mx) : m_mx(mx.m_mx) {}
> ~mutex_accessor() {} // intentionally nonvirtual
>
> void lock() { m_mx.lock(); }
> bool trylock() { return m_mx.trylock(); }
> bool timedlock(int milliseconds) { return
> m_mx.timedlock(milliseconds); }
> void unlock() { m_mx.unlock(); }
>
> private:
> M::impl& m_mx;
> };
>
> Now, if I were to think of a useful lock type that you hadn't
thought of, I
> could implement it by deriving from mutex_accessor<>.
That's precisely what I thought you meant. However, mutex_accessor<>
is publicly available, so it provides no added security (only a
psychological one, which I suppose may be a valid argument... after
all that's one reason why I'm ok with unsafe_lock<>). Given that the
thousand dollar question is why you just didn't expose this on mutex
to begin with.
> > As for why I prefer placement new... it's wholly generic. It
doesn't
> > require specialized coding when a programmer adds a new
> > implementation of a Mutex concept, nor does it impose any further
> > requirements on the implementation beyond those required by the
> > concept. The feeling that it's "hackish" is irrelevant, since
it's a
> > hidden part of the implementation.
>
> I'm suggesting that it might be possible, through use of
mutex_accessor<>,
> to provide an interface that can be extended more easily, without
> sacrificing safety for basic use.
I understand what you're saying, but I think this is no different
from exposing this functionality on mutex directly.
Bill Kempf
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk