2005-11-19 22:00:23 +00:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// The Loki Library
|
|
|
|
|
// Copyright (c) 2001 by Andrei Alexandrescu
|
|
|
|
|
// This code is from the article:
|
|
|
|
|
// "Generic<Programming>: volatile <20> Multithreaded Programmer<65>s Best Friend
|
|
|
|
|
// Volatile-Correctness or How to Have Your Compiler Detect Race Conditions
|
|
|
|
|
// for You" by Alexandrescu, Andrei.
|
|
|
|
|
// Published in the February 2001 issue of the C/C++ Users Journal.
|
|
|
|
|
// http://www.cuj.com/documents/s=7998/cujcexp1902alexandr/
|
|
|
|
|
// Prepared for Loki library by Richard Sposato
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// $Header$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef LOKI_LOCKING_PTR_INC_
|
|
|
|
|
#define LOKI_LOCKING_PTR_INC_
|
|
|
|
|
|
|
|
|
|
namespace Loki
|
|
|
|
|
{
|
|
|
|
|
|
2006-01-21 14:13:48 +00:00
|
|
|
|
template<class T>
|
|
|
|
|
struct NonConstObject
|
|
|
|
|
{
|
|
|
|
|
typedef T Type;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
struct ConstObject
|
|
|
|
|
{
|
|
|
|
|
typedef const T Type;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-11-19 22:00:23 +00:00
|
|
|
|
/** @class LockingPtr
|
|
|
|
|
Locks a volatile object and casts away volatility so that the object
|
|
|
|
|
can be safely used in a single-threaded region of code.
|
|
|
|
|
Original version of LockingPtr had only one template - for the shared
|
|
|
|
|
object, but not the mutex type. This version allows users to specify a
|
|
|
|
|
the mutex type as a LockingPolicy class. The only requirements for a
|
|
|
|
|
LockingPolicy class are to provide Lock and Unlock methods.
|
|
|
|
|
*/
|
2006-01-21 14:13:48 +00:00
|
|
|
|
template < typename SharedObject, typename LockingPolicy = Loki::Mutex,
|
|
|
|
|
template<class> class ConstPolicy = NonConstObject >
|
2005-11-19 22:00:23 +00:00
|
|
|
|
class LockingPtr
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
2006-01-21 14:13:48 +00:00
|
|
|
|
typedef typename ConstPolicy<SharedObject>::Type ConstOrNotType;
|
|
|
|
|
|
2005-11-19 22:00:23 +00:00
|
|
|
|
/** Constructor locks mutex associated with an object.
|
|
|
|
|
@param obj Reference to object.
|
|
|
|
|
@param mtx Mutex used to control thread access to object.
|
|
|
|
|
*/
|
2006-01-21 14:13:48 +00:00
|
|
|
|
LockingPtr( volatile ConstOrNotType & object, LockingPolicy & mutex )
|
2005-11-19 22:00:23 +00:00
|
|
|
|
: pObject_( const_cast< SharedObject * >( &object ) ),
|
|
|
|
|
pMutex_( &mutex )
|
|
|
|
|
{
|
|
|
|
|
mutex.Lock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Destructor unlocks the mutex.
|
|
|
|
|
~LockingPtr()
|
|
|
|
|
{
|
|
|
|
|
pMutex_->Unlock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Star-operator dereferences pointer.
|
2006-01-21 14:13:48 +00:00
|
|
|
|
ConstOrNotType & operator * ()
|
2005-11-19 22:00:23 +00:00
|
|
|
|
{
|
|
|
|
|
return *pObject_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Point-operator returns pointer to object.
|
2006-01-21 14:13:48 +00:00
|
|
|
|
ConstOrNotType * operator -> ()
|
2005-11-19 22:00:23 +00:00
|
|
|
|
{
|
|
|
|
|
return pObject_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
/// Default constructor is not implemented.
|
|
|
|
|
LockingPtr();
|
|
|
|
|
|
|
|
|
|
/// Copy-constructor is not implemented.
|
|
|
|
|
LockingPtr( const LockingPtr & );
|
|
|
|
|
|
|
|
|
|
/// Copy-assignment-operator is not implemented.
|
|
|
|
|
LockingPtr & operator = ( const LockingPtr & );
|
|
|
|
|
|
|
|
|
|
/// Pointer to the shared object.
|
2006-01-21 14:13:48 +00:00
|
|
|
|
ConstOrNotType * pObject_;
|
2005-11-19 22:00:23 +00:00
|
|
|
|
|
|
|
|
|
/// Pointer to the mutex.
|
|
|
|
|
LockingPolicy * pMutex_;
|
|
|
|
|
|
|
|
|
|
}; // end class LockingPtr
|
|
|
|
|
|
2006-01-21 14:13:48 +00:00
|
|
|
|
|
|
|
|
|
template<typename SharedObject, typename LockingPolicy = Mutex>
|
|
|
|
|
struct Locking
|
|
|
|
|
{
|
|
|
|
|
typedef LockingPtr<SharedObject, LockingPolicy, NonConstObject> Ptr;
|
|
|
|
|
typedef LockingPtr<SharedObject, LockingPolicy, ConstObject> ConstPtr;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
2006-01-19 19:36:34 +00:00
|
|
|
|
/** @class ConstLockingPtr
|
|
|
|
|
Similar to LockingPtr, except that it returns pointers and references to
|
|
|
|
|
a const SharedObject instead of a mutuable SharedObject.
|
|
|
|
|
@see LockingPtr
|
|
|
|
|
*/
|
2006-01-21 01:02:12 +00:00
|
|
|
|
template < typename SharedObject, typename LockingPolicy = Loki::Mutex >
|
2006-01-19 19:36:34 +00:00
|
|
|
|
class ConstLockingPtr
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
/** Constructor locks mutex associated with an object.
|
|
|
|
|
@param obj Reference to const object.
|
|
|
|
|
@param mtx Mutex used to control thread access to object.
|
|
|
|
|
*/
|
|
|
|
|
ConstLockingPtr( volatile const SharedObject & object,
|
|
|
|
|
LockingPolicy & mutex )
|
|
|
|
|
: pObject_( const_cast< const SharedObject * >( &object ) ),
|
|
|
|
|
pMutex_( &mutex )
|
|
|
|
|
{
|
|
|
|
|
mutex.Lock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Destructor unlocks the mutex.
|
|
|
|
|
~ConstLockingPtr()
|
|
|
|
|
{
|
|
|
|
|
pMutex_->Unlock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Star-operator dereferences pointer.
|
|
|
|
|
const SharedObject & operator * ()
|
|
|
|
|
{
|
|
|
|
|
return *pObject_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Point-operator returns pointer to object.
|
|
|
|
|
const SharedObject * operator -> ()
|
|
|
|
|
{
|
|
|
|
|
return pObject_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
/// Default constructor is not implemented.
|
|
|
|
|
ConstLockingPtr();
|
|
|
|
|
|
|
|
|
|
/// Copy-constructor is not implemented.
|
|
|
|
|
ConstLockingPtr( const ConstLockingPtr & );
|
|
|
|
|
|
|
|
|
|
/// Copy-assignment-operator is not implemented.
|
|
|
|
|
ConstLockingPtr & operator = ( const ConstLockingPtr & );
|
|
|
|
|
|
|
|
|
|
/// Pointer to the shared object.
|
|
|
|
|
const SharedObject * pObject_;
|
|
|
|
|
|
|
|
|
|
/// Pointer to the mutex.
|
|
|
|
|
LockingPolicy * pMutex_;
|
|
|
|
|
|
|
|
|
|
}; // end class ConstLockingPtr
|
2006-01-21 14:13:48 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2006-01-19 19:36:34 +00:00
|
|
|
|
|
2005-11-19 22:00:23 +00:00
|
|
|
|
} // namespace Loki
|
|
|
|
|
|
|
|
|
|
#endif // end file guardian
|
|
|
|
|
|
2006-01-21 14:13:48 +00:00
|
|
|
|
|
|
|
|
|
|
2005-11-19 22:00:23 +00:00
|
|
|
|
// $Log$
|
2006-01-21 14:13:48 +00:00
|
|
|
|
// Revision 1.6 2006/01/21 14:09:09 syntheticpp
|
|
|
|
|
// replace LockPtr/ConstLockPtr implementation with a template policy based one
|
|
|
|
|
//
|
2006-01-21 01:02:12 +00:00
|
|
|
|
// Revision 1.5 2006/01/21 01:02:12 rich_sposato
|
|
|
|
|
// Added Mutex class to Loki. Made it the default policy class for locking.
|
|
|
|
|
//
|
2006-01-19 19:36:34 +00:00
|
|
|
|
// Revision 1.4 2006/01/19 19:34:19 rich_sposato
|
|
|
|
|
// Added ConstLockingPtr class.
|
|
|
|
|
//
|
2006-01-16 18:34:37 +00:00
|
|
|
|
// Revision 1.3 2006/01/16 18:34:37 rich_sposato
|
|
|
|
|
// Changed return type from LockingPtr to SharedObject.
|
|
|
|
|
//
|
2006-01-14 00:20:10 +00:00
|
|
|
|
// Revision 1.2 2006/01/14 00:20:10 syntheticpp
|
|
|
|
|
// remove c&p error
|
|
|
|
|
//
|
2005-11-19 22:00:23 +00:00
|
|
|
|
// Revision 1.1 2005/11/19 22:00:23 rich_sposato
|
|
|
|
|
// Adding LockingPtr class to Loki project.
|
|
|
|
|
//
|