Boost logo

Boost :

From: Eric D Crahen (crahen_at_[hidden])
Date: 2002-05-17 12:23:28


Couldn't a simple policy based template be used instead of move
semantics? The syntax is almost identical, and the flow of the
code is easier to follow without the ownership issues. All I did
was to make the behavioral-scope of the lock be controlled by a
boolean rather than by the lifetime of the template that encapusaltes
it; so it can end prematurety to deal with overlapped locks.

I modified the template I've been using in my thread library to
demonstrate this. I've been calling it Guard, which seems even
more appropriate now in the sense that scopes by nature are nested
things and don't overlap.

// Example code

// Policy for acquire then release
class ForwardLocking {
public:

  template <class LockType>
  static void acquire(LockType& lock) { lock.acquire(); }

  template <class LockType>
  static void release(LockType& lock) { lock.release(); }

};

// Policy for release then acquire
class BackwardsLocking {
public:

  template <class LockType>
  static void acquire(LockType& lock) { lock.release(); }

  template <class LockType>
  static void release(LockType& lock) { lock.acquire(); }

};

// Guard/ScopedLock template
template <class LockType, class Strategy = ForwardLocking>
class Guard : protected Strategy {

  LockType& _lock;
  volatile bool _active; // control the behavioral scope

public:

  // Overlapped scopes
  template <class Y, class Z>
  Guard(Guard<Y, Z>& guard, LockType& lock) : _lock(lock), _active(true) {
    acquire();
    guard.release();
  }

  // Nested or non-nested scopes
  Guard(LockType& lock) : _lock(lock), _active(true) {
    acquire();
  }

  ~Guard() {
    release();
  }

private:

  // Acquire the lock, activate the scope
  void acquire() {
    _active = true;
    Strategy::acquire(_lock);
  }

  // Release the lock, deactivate the scope
  void release() {

   if(_active) {

      Strategy::release(_lock);
      _active = false;

    }

  }

};

//
// Example usage
//

void aFunction() {

  Mutex mtx1, mtx2;

  Guard<Mutex> g1(mtx1);

  // mtx1 locked

  { // Nested scope

    Guard<Mutex, BackwardsLocking> g2(mtx1);

    // mtx1 unlocked

  }

  // mtx1 locked

  // overlapped scopes, move from g1's scope to a new one
  Guard<Mutex> g3(g1, mtx2);

  // mtx1 unlocked, mtx2 locked

}

This is just a quick implementation, but is there anything that move
semantics would allow that you can't accomplish with a template like
this (or along these lines anyways)? I think something like this may
be a little easier to understand and use.

- Eric
http://www.cse.buffalo.edu/~crahen


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