Boost logo

Boost Users :

From: Raoul Gough (yg-boost-users_at_[hidden])
Date: 2002-09-27 06:44:03


boost::scoped_lock is non-copyable, so it is impossible to return one
from a function by value. However, I would like to be able to do
something like this:

mt::holder<std::ostream> logStream;

logStream() << "Hello world\n";

where the operator() returns a proxy object that contains a
scoped_lock and a pointer to the data (the ostream). What I currently
have is this:

(mt::proxy<std::ostream> (logStream)) << "Hello world\n";

So the client code has to know what type the proxy object is and
construct one itself. If scoped_lock would provide access to its
associated mutex object, this wouldn't be a necessary, because the
proxy object could then have a copy-constructor, and operator() in the
holder template would look like this:

  proxy<T> operator() ()
  {
    proxy<T> temp (*this);
    return temp;
  }

The proxy copy constructor would unlock() the original lock and
construct the copy using the original's mutex (which is the part that
can't currently work, because there is no public access to a lock's
mutex). Assuming that the compiler implements the NRVO, the
unlock/lock sequence wouldn't actually happen, and the client code
just gets its proxy object constructed for it. If the compiler doesn't
implement the NRVO, the code still works, but is less efficient.

I guess exposing the raw mutex from scoped_lock would break an
important level of encapsulation. Still, it would be kind of nice in
this case. Maybe if proxy<T> were part of the library and made a
friend of scoped_lock? The only other alternative I've come up with is
to allocate the lock on the heap and return an object containing a
std::auto_ptr (which makes usage easier, but less efficient). Any
comments or suggestions?

Regards,
Raoul Gough.

// Returnable proxy template

  template<typename T>
  class proxy
  {
    boost::mutex::scoped_lock mLock;
    T *mPtr;

    boost::mutex &release()
   {
      mLock.unlock();
      return mLock.mutex(); // <<<< doesn't work
    }

  public:

    proxy (proxy &other)
      : mLock (other.release())
      , mPtr (other.mPtr)
    {
    }

    // ...
  };


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net