replace LockPtr/ConstLockPtr implementation with a template policy based one

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@508 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
syntheticpp 2006-01-21 14:13:48 +00:00
parent 2ada6bd1d7
commit 5e5965fdc1
3 changed files with 57 additions and 17 deletions

View file

@ -19,6 +19,20 @@
namespace Loki namespace Loki
{ {
template<class T>
struct NonConstObject
{
typedef T Type;
};
template<class T>
struct ConstObject
{
typedef const T Type;
};
/** @class LockingPtr /** @class LockingPtr
Locks a volatile object and casts away volatility so that the object Locks a volatile object and casts away volatility so that the object
can be safely used in a single-threaded region of code. can be safely used in a single-threaded region of code.
@ -27,16 +41,19 @@ namespace Loki
the mutex type as a LockingPolicy class. The only requirements for a the mutex type as a LockingPolicy class. The only requirements for a
LockingPolicy class are to provide Lock and Unlock methods. LockingPolicy class are to provide Lock and Unlock methods.
*/ */
template < typename SharedObject, typename LockingPolicy = Loki::Mutex > template < typename SharedObject, typename LockingPolicy = Loki::Mutex,
template<class> class ConstPolicy = NonConstObject >
class LockingPtr class LockingPtr
{ {
public: public:
typedef typename ConstPolicy<SharedObject>::Type ConstOrNotType;
/** Constructor locks mutex associated with an object. /** Constructor locks mutex associated with an object.
@param obj Reference to object. @param obj Reference to object.
@param mtx Mutex used to control thread access to object. @param mtx Mutex used to control thread access to object.
*/ */
LockingPtr( volatile SharedObject & object, LockingPolicy & mutex ) LockingPtr( volatile ConstOrNotType & object, LockingPolicy & mutex )
: pObject_( const_cast< SharedObject * >( &object ) ), : pObject_( const_cast< SharedObject * >( &object ) ),
pMutex_( &mutex ) pMutex_( &mutex )
{ {
@ -50,13 +67,13 @@ namespace Loki
} }
/// Star-operator dereferences pointer. /// Star-operator dereferences pointer.
SharedObject & operator * () ConstOrNotType & operator * ()
{ {
return *pObject_; return *pObject_;
} }
/// Point-operator returns pointer to object. /// Point-operator returns pointer to object.
SharedObject * operator -> () ConstOrNotType * operator -> ()
{ {
return pObject_; return pObject_;
} }
@ -73,13 +90,23 @@ namespace Loki
LockingPtr & operator = ( const LockingPtr & ); LockingPtr & operator = ( const LockingPtr & );
/// Pointer to the shared object. /// Pointer to the shared object.
SharedObject * pObject_; ConstOrNotType * pObject_;
/// Pointer to the mutex. /// Pointer to the mutex.
LockingPolicy * pMutex_; LockingPolicy * pMutex_;
}; // end class LockingPtr }; // end class LockingPtr
template<typename SharedObject, typename LockingPolicy = Mutex>
struct Locking
{
typedef LockingPtr<SharedObject, LockingPolicy, NonConstObject> Ptr;
typedef LockingPtr<SharedObject, LockingPolicy, ConstObject> ConstPtr;
};
#if 0
/** @class ConstLockingPtr /** @class ConstLockingPtr
Similar to LockingPtr, except that it returns pointers and references to Similar to LockingPtr, except that it returns pointers and references to
a const SharedObject instead of a mutuable SharedObject. a const SharedObject instead of a mutuable SharedObject.
@ -138,12 +165,19 @@ namespace Loki
LockingPolicy * pMutex_; LockingPolicy * pMutex_;
}; // end class ConstLockingPtr }; // end class ConstLockingPtr
#endif
} // namespace Loki } // namespace Loki
#endif // end file guardian #endif // end file guardian
// $Log$ // $Log$
// Revision 1.6 2006/01/21 14:09:09 syntheticpp
// replace LockPtr/ConstLockPtr implementation with a template policy based one
//
// Revision 1.5 2006/01/21 01:02:12 rich_sposato // Revision 1.5 2006/01/21 01:02:12 rich_sposato
// Added Mutex class to Loki. Made it the default policy class for locking. // Added Mutex class to Loki. Made it the default policy class for locking.
// //

View file

@ -206,10 +206,6 @@
RelativePath="..\..\include\loki\HierarchyGenerators.h" RelativePath="..\..\include\loki\HierarchyGenerators.h"
> >
</File> </File>
<File
RelativePath="..\..\include\loki\LockingPtr.h"
>
</File>
<File <File
RelativePath="..\..\include\loki\LokiTypeInfo.h" RelativePath="..\..\include\loki\LokiTypeInfo.h"
> >
@ -254,10 +250,6 @@
RelativePath="..\..\include\loki\static_check.h" RelativePath="..\..\include\loki\static_check.h"
> >
</File> </File>
<File
RelativePath="..\..\include\loki\Threads.h"
>
</File>
<File <File
RelativePath="..\..\include\loki\Tuple.h" RelativePath="..\..\include\loki\Tuple.h"
> >
@ -324,6 +316,10 @@
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
> >
<File
RelativePath="..\..\include\loki\LockingPtr.h"
>
</File>
<File <File
RelativePath=".\main.cpp" RelativePath=".\main.cpp"
> >
@ -332,6 +328,10 @@
RelativePath=".\Thread.h" RelativePath=".\Thread.h"
> >
</File> </File>
<File
RelativePath="..\..\include\loki\Threads.h"
>
</File>
</Filter> </Filter>
</Files> </Files>
<Globals> <Globals>

View file

@ -14,6 +14,10 @@
#define LOKI_CLASS_LEVEL_THREADING #define LOKI_CLASS_LEVEL_THREADING
#ifndef LOKI_CLASS_LEVEL_THREADING
#define LOKI_OBJECT_LEVEL_THREADING
#endif
#include "Thread.h" #include "Thread.h"
#include <loki/LockingPtr.h> #include <loki/LockingPtr.h>
@ -29,6 +33,8 @@ int loop = 5;
struct A struct A
{ {
A(){};
#define DO for(int i=0; i<10000000; i++) g++; #define DO for(int i=0; i<10000000; i++) g++;
void print(void* id) const void print(void* id) const
@ -54,8 +60,8 @@ struct A
} }
}; };
typedef Loki::LockingPtr<A,Loki::Mutex> LPtr; typedef Loki::Locking<A>::Ptr LPtr;
typedef Loki::ConstLockingPtr<A,Loki::Mutex> CLPtr; typedef Loki::Locking<A>::ConstPtr CLPtr;
void* RunLocked(void *id) void* RunLocked(void *id)
{ {
@ -96,7 +102,7 @@ int main ()
for(int i=0; i<numThreads; i++) for(int i=0; i<numThreads; i++)
{ {
Printf("Creating thread %d\n")(i); Printf("Creating thread %d\n")(i);
threads.push_back(new Thread(RunLocked,(void*)i)); threads.push_back(new Thread(RunLocked,reinterpret_cast<void*>(i)));
} }
for(int i=0; i<numThreads; i++) for(int i=0; i<numThreads; i++)
threads.at(i)->start(); threads.at(i)->start();
@ -111,7 +117,7 @@ int main ()
for(int i=0; i<numThreads; i++) for(int i=0; i<numThreads; i++)
{ {
Printf("Creating thread %d\n")(i); Printf("Creating thread %d\n")(i);
threads.push_back(new Thread(Run,(void*)i)); threads.push_back(new Thread(Run,reinterpret_cast<void*>(i)));
} }
for(int i=0; i<numThreads; i++) for(int i=0; i<numThreads; i++)
threads.at(i)->start(); threads.at(i)->start();