]> git.cworth.org Git - vogl/blob - src/extlib/loki/include/loki/LockingPtr.h
Initial vogl checkin
[vogl] / src / extlib / loki / include / loki / LockingPtr.h
1 ////////////////////////////////////////////////////////////////////////////////
2 // The Loki Library
3 // Copyright (c) 2001 by Andrei Alexandrescu
4 // This code is from the article:
5 //     "Generic<Programming>: volatile \97 Multithreaded Programmer\92s Best Friend
6 //     Volatile-Correctness or How to Have Your Compiler Detect Race Conditions
7 //     for You" by Alexandrescu, Andrei.
8 //     Published in the February 2001 issue of the C/C++ Users Journal.
9 //     http://www.cuj.com/documents/s=7998/cujcexp1902alexandr/
10 // Permission to use, copy, modify, distribute and sell this software for any
11 //     purpose is hereby granted without fee, provided that the above copyright
12 //     notice appear in all copies and that both that copyright notice and this
13 //     permission notice appear in supporting documentation.
14 // The author makes no representations about the
15 //     suitability of this software for any purpose. It is provided "as is"
16 //     without express or implied warranty.
17 // Prepared for Loki library by Richard Sposato
18 ////////////////////////////////////////////////////////////////////////////////
19 #ifndef LOKI_LOCKING_PTR_INC_
20 #define LOKI_LOCKING_PTR_INC_
21
22 // $Id: LockingPtr.h 840 2008-03-19 19:44:38Z rich_sposato $
23
24
25 #include <loki/ConstPolicy.h>
26 #include <loki/Threads.h>
27
28
29 namespace Loki
30 {
31 /** @class LockingPtr
32  Locks a volatile object and casts away volatility so that the object
33  can be safely used in a single-threaded region of code.
34  Original version of LockingPtr had only one template - for the shared
35  object, but not the mutex type.  This version allows users to specify a
36  the mutex type as a LockingPolicy class.  The only requirements for a
37  LockingPolicy class are to provide Lock and Unlock methods.
38  */
39 template < typename SharedObject, typename LockingPolicy = LOKI_DEFAULT_MUTEX,
40          template<class> class ConstPolicy = LOKI_DEFAULT_CONSTNESS >
41 class LockingPtr
42 {
43 public:
44
45         typedef typename ConstPolicy<SharedObject>::Type ConstOrNotType;
46
47         /** Constructor locks mutex associated with an object.
48          @param object Reference to object.
49          @param mutex Mutex used to control thread access to object.
50          */
51         LockingPtr( volatile ConstOrNotType &object, LockingPolicy &mutex )
52                 : pObject_( const_cast< SharedObject * >( &object ) ),
53                   pMutex_( &mutex )
54         {
55                 mutex.Lock();
56         }
57
58         typedef typename std::pair<volatile ConstOrNotType *, LockingPolicy *> Pair;
59
60         /** Constructor locks mutex associated with an object.
61          @param lockpair a std::pair of pointers to the object and the mutex
62          */
63         LockingPtr( Pair lockpair )
64                 : pObject_( const_cast< SharedObject * >( lockpair.first ) ),
65                   pMutex_( lockpair.second )
66         {
67                 lockpair.second->Lock();
68         }
69
70         /// Destructor unlocks the mutex.
71         ~LockingPtr()
72         {
73                 pMutex_->Unlock();
74         }
75
76         /// Star-operator dereferences pointer.
77         ConstOrNotType &operator * ()
78         {
79                 return *pObject_;
80         }
81
82         /// Point-operator returns pointer to object.
83         ConstOrNotType *operator -> ()
84         {
85                 return pObject_;
86         }
87
88 private:
89
90         /// Default constructor is not implemented.
91         LockingPtr();
92
93         /// Copy-constructor is not implemented.
94         LockingPtr( const LockingPtr & );
95
96         /// Copy-assignment-operator is not implemented.
97         LockingPtr &operator = ( const LockingPtr & );
98
99         /// Pointer to the shared object.
100         ConstOrNotType *pObject_;
101
102         /// Pointer to the mutex.
103         LockingPolicy *pMutex_;
104
105 }; // end class LockingPtr
106
107 } // namespace Loki
108
109 #endif // end file guardian
110