Boost logo

Boost :

From: Daniel Frey (d.frey_at_[hidden])
Date: 2008-04-25 15:33:33


Replying to myself, again... hm...

On Fri, 2008-04-25 at 09:09 +0200, Daniel Frey wrote:
> On Thu, 2008-04-24 at 23:23 -0400, Frank Mori Hess wrote:
> > On Thursday 24 April 2008 21:22, Daniel Frey wrote:
> > > I prepared a patch for the documentation. While doing that, I noticed
> > > that the current ctor is a template ctor, which it should not be. Is:
> >
> > What's the point of documenting an unspecified reference counter type?
> > Following the interface specified by the docs, the only thing you can do
> > with get_shared_count() is pass its return value directly to the
> > constructor that takes a shared_count. That adds nothing over the
> > aliasing constructor. You can't store the return value in a shared_count,
> > because it's an unspecified type.
>
> [...]

Another point: Documenting this interface might not be the end. As a
next step, one could consider to document the reference counter type
(currently detail::shared_count) and its interface - at least a usable
part of it. Which part might be useful and what benefits would it
provide? What's a use case for it? I often use a shared_ptr<void> as a
holder for mutex locks. Think of the mutex interface like this:

namespace X {

typedef shared_ptr<void> lock;

struct mutex
{
  mutex();

  X::lock lock();
  X::lock try_lock();
  X::lock timed_lock( unsigned ms );

private:
  void unlock();
};

// v is accessed from different threads
std::vector<foo> v;
mutex m;

void process_back()
{
  lock l = m.lock();

  if( v.empty() )
    return;

  foo f = v.back();

  // release the lock here
  l.reset();

  // still use f here
  ...
}

} // namespace X

The deleter of the returned X::lock calls mutext::unlock(). I also have
another class X::rwmutex, which also uses X::lock, no need to define a
second lock type.

I often use l.reset() to free the lock before the scope it was defined
in ends. I've often seen people using extra scopes for this, but this
might conflict with other scopes and the lifetime of other variables.

Other useful features are reassigning a lock and storing it (copy it
somewhere). All of this come from shared_ptr<void> and the additional
power is worth the overhead of the reference counter. What is never used
(unlike the stored reference counter) is the void* itself that is stored
inside the lock, so just using "typedef detail::shared_count lock;"
should be enough and would reduce the overhead without loosing any
functionality. Of course the interface of detail::shared_count should
match shared_ptr's interface, i.e. .empty() should be turned into a bool
conversion and there should be a .reset()-method. And some useful ctors.
Probably not much more, but it all depends on what makes a good use
case.

Anyway, I'm not proposing this for now, just some thoughts on why it
might be desirable to document the interface with
unspecified-reference-counter-type.

Regards, Daniel


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