EPICS Base  7.0.6.1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
epicsGuard.h
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * SPDX-License-Identifier: EPICS
7 * EPICS Base is distributed subject to a Software License Agreement found
8 * in file LICENSE that is included with this distribution.
9 \*************************************************************************/
10 
11 #ifndef epicsGuardh
12 #define epicsGuardh
13 
14 #ifndef assert // allow use of epicsAssert.h
15 # include <cassert>
16 #endif
17 
18 /*
19  * Author: Jeffrey O. Hill
20  */
21 
22 template < class T > class epicsGuardRelease;
23 
24 // Automatically applies and releases the mutex.
25 // This class is also useful in situations where
26 // C++ exceptions are possible.
27 template < class T >
28 class epicsGuard {
29 public:
31  epicsGuard ( T & );
32  void assertIdenticalMutex ( const T & ) const;
33  ~epicsGuard ();
34 private:
35  T * _pTargetMutex;
36  epicsGuard ( const epicsGuard & );
37  epicsGuard & operator = ( const epicsGuard & );
38  friend class epicsGuardRelease < T >;
39 };
40 
41 // Automatically releases and reapplies the mutex.
42 // This class is also useful in situations where
43 // C++ exceptions are possible.
44 template < class T >
45 class epicsGuardRelease {
46 public:
47  typedef epicsGuard<T> guard_t;
50 private:
51  epicsGuard < T > & _guard;
52  T * _pTargetMutex;
54  epicsGuardRelease & operator = ( const epicsGuardRelease & );
55 };
56 
57 // same interface as epicsMutex
59 public:
60  void lock ();
61  bool tryLock ();
62  void unlock ();
63  void show ( unsigned level ) const;
64 };
65 
66 template < class T >
67 inline epicsGuard < T > :: epicsGuard ( T & mutexIn ) :
68  _pTargetMutex ( & mutexIn )
69 {
70  _pTargetMutex->lock ();
71 }
72 
73 template < class T >
74 inline epicsGuard < T > :: ~epicsGuard ()
75 {
76  _pTargetMutex->unlock ();
77 }
78 
79 template < class T >
80 inline void epicsGuard < T > :: assertIdenticalMutex (
81  const T & mutexToVerify ) const
82 {
83  assert ( _pTargetMutex == & mutexToVerify );
84 }
85 
86 template < class T >
88  epicsGuardRelease ( epicsGuard<T> & guardIn ) :
89  _guard ( guardIn ),
90  _pTargetMutex ( guardIn._pTargetMutex )
91 {
92  // Setting the guard's _pTargetMutex to nill will
93  // allow assertIdenticalMutex to catch situations
94  // where a guard is being used and it has been
95  // released, and also situations where ~epicsGuard ()
96  // runs and an epicsGuardRelease is still referencing
97  // the guard will be detected.
98  _guard._pTargetMutex = 0;
99  _pTargetMutex->unlock ();
100 }
101 
102 template < class T >
103 inline epicsGuardRelease < T > :: ~epicsGuardRelease ()
104 {
105  _pTargetMutex->lock ();
106  _guard._pTargetMutex = _pTargetMutex;
107 }
108 
109 inline void epicsMutexNOOP::lock () {}
110 inline bool epicsMutexNOOP::tryLock () { return true; }
111 inline void epicsMutexNOOP::unlock () {}
112 inline void epicsMutexNOOP::show ( unsigned ) const {}
113 
114 #endif // epicsGuardh
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:71