Boost logo

Boost :

From: Hamish Mackenzie (hamish_at_[hidden])
Date: 2003-02-06 20:14:23


On Thu, 2003-02-06 at 18:52, Trey Jackson wrote:
> Hamish Mackenzie wrote:
> >These scoped locks will go out of scope before you "do stuff".
>
> Right, thanks for the catch.
>
> I started writing it thinking I'd be doing some cool new
> meta-programming, but it turned into just simple object inheritance
> (thus the function calls that let the locks go out of scope).
>
> But my original intent was actually to try to get code substituted at
> compile time.

I think you had that bit right. Here is a more complete version of what
I think you wanted with a couple of syntax errors corrected.

template<class LockingStrategy> // perhaps "locking policy"
class mySuperLockedClass : public LockingStrategy
{
public:
  void read()
  {
    typename LockingStrategy::read_lock_type l( this );
    // do stuff
  }
  void write()
  {
    typename LockingStrategy::write_lock_type l( this );
    // do stuff
  }
};

class
EmptyLockingStrategy
{
  struct lock_type : boost::noncopyable
  {
    lock_type( EmptyLockingStrategy * s ) {}
  };
public:
  typedef lock_type read_lock_type;
  typedef lock_type write_lock_type;
};

class
MutexLockingStrategy
{
  boost::mutex m_;
  class lock_type less a couple syntax errors
  {
  public:
    lock_type( MutexLockingStrategy * s ) : l_( s->m_ ) {}
  private:
    boost::mutex::scoped_lock l_;
  };
public:
  typedef lock_type read_lock_type;
  typedef lock_type write_lock_type;
};

class
ReaderWriterLockingStrategy
{
  boost::unimplemented::rwmutex m_;
public:
  class read_lock_type
  {
  public:
    read_lock_type( ReaderWriterLockingStrategy * s ) : l_( s->m_ ) {}
  private:
    boost::unimplemented::rwmutex::scoped_read_lock l_;
  };
  class write_lock_type
  {
  public:
    write_lock_type( ReaderWriterLockingStrategy * s ) : l_( s->m_ ) {}
  private:
    boost::unimplemented::rwmutex::scoped_write_lock l_;
  };
};

The only thing different from your original is that this uses RAII
(resource acquisition is initialization) to insert code in two places
(lock and unlock). You can put whatever other code you like in the
constructor and destructor of read_lock_type and write_lock_type.

You could have stuck with your original approach and used four functions
(read_lock, read_unlock, write_lock and write_unlock). Then added the
RAII later as a separate template class, but I think that would make the
implementation unnecessarily messy for the same end result.

> Any tips on how to do this?
> Is it possible in C++? I can see how to do it with lisp macros.
> I'm reading the MPL intro written by David Abrahams and Aleskey
> Gurtovoy, but it's slow going...

It is also worth checking out Modern C++ Design by Andrei Alexandrescu
if you haven't already. In particular the stuff on policies.

-- 
Hamish Mackenzie <hamish_at_[hidden]>

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