$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: William E. Kempf (williamkempf_at_[hidden])
Date: 2002-05-17 13:05:35
----- Original Message -----
From: "Eric D Crahen" <crahen_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, May 17, 2002 12:23 PM
Subject: [boost] Re: Boost.Threads Locking Delima (William E. Kempf)
>
> 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();
>   }
This doesn't transfer ownership of a lock across scopes.  It overlaps locks
on two different mutexes (where you use LockType Boost.Threads uses Mutex...
locks are not mutexes but are locks on a mutex).
>   // 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.
As I said above, this doesn't allow us to transfer a lock out of one scope
and into another, it only allows overlapped locks, and I think Boost.Threads
has a better solution for this today.  Read Bjarne's article I posted in the
first message in this thread and try to implement a locking_ptr<> using
either the current Boost.Threads ScopedLocks or the above Guard to see
precisely where the problem lies.
Bill Kempf