Free Electron
Safe.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __core_Safe_h__
8 #define __core_Safe_h__
9 
10 //#define FE_DISABLE_THREAD_SAFE
11 
12 #define SAFEGUARD FEASSERT(fe_thread_mutex()); \
13  SafeGuard __fe_thread_safeguard( \
14  fe_thread_mutex());
15 #define SAFEGUARD_IF(X) FEASSERT(fe_thread_mutex()); \
16  SafeGuard __fe_thread_safeguard( \
17  fe_thread_mutex(),X);
18 #define SAFEUNLOCK __fe_thread_safeguard.unlock();
19 #define SAFELOCK __fe_thread_safeguard.lock();
20 
21 #define SAFEGUARDCLASS FEASSERT(fe_class_thread_mutex()); \
22  SafeGuard __fe_class_thread_safeguard( \
23  fe_class_thread_mutex());
24 #define SAFEGUARDCLASS_IF(X) FEASSERT(fe_class_thread_mutex()); \
25  SafeGuard __fe_class_thread_safeguard( \
26  fe_class_thread_mutex(),X);
27 #define SAFEUNLOCKCLASS __fe_class_thread_safeguard.unlock();
28 #define SAFELOCKCLASS __fe_class_thread_safeguard.lock();
29 
30 namespace fe
31 {
32 
33 class SafeBase
34 {
35  public:
36 virtual ~SafeBase(void) {}
37  // returns a pointer because NotSafe does not require a mutex
38 virtual RecursiveMutex* fe_thread_mutex(void) const =0;
39 };
40 
41 class ClassSafeBase
42 {
43  public:
44 virtual ~ClassSafeBase(void) {}
45  // returns a pointer because NotSafe does not require a mutex
46 virtual RecursiveMutex* fe_class_thread_mutex(void) const =0;
47 };
48 
49 template <typename T>
50 class FE_DL_EXPORT trueClassSafe : public ClassSafeBase
51 {
52  public:
53  class FE_DL_PUBLIC SafeGuard
54  {
55  public:
56  SafeGuard(RecursiveMutex *mutex,BWORD a_truly=TRUE):
57  m_guard(*mutex,FALSE,a_truly) {}
58  void lock(void) { m_guard.lock(); }
59  void unlock(void) { m_guard.unlock(); }
60 
61  RecursiveMutex::Guard&
62  guard(void) { return m_guard; }
63 
64  private:
65  RecursiveMutex::Guard m_guard;
66  };
67 
68 #if FE_SAFE_COUNTED_MUTEX
69  trueClassSafe(void)
70  {
71 // feLog("%p trueClassSafe<%s> %d %p %p\n",
72 // this,FE_TYPESTRING(T).c_str(),
73 // ms_mutexCount,&ms_pMutex,ms_pMutex);
74 
75 // if(ms_mutexCount++ == 0)
76  if(!feAsmSwapIncr(&ms_mutexCount,1) && !ms_pMutex)
77  {
78  ms_pMutex=new RecursiveMutex;
79  Memory::markForDeath(ms_pMutex,&ms_mutexCount);
80  }
81  FEASSERT(ms_pMutex);
82  }
83 
84 virtual ~trueClassSafe(void)
85  {
86 // feLog("%p ~trueClassSafe<%s> %d %p %p\n",
87 // this,FE_TYPESTRING(T).c_str(),
88 // ms_mutexCount,&ms_pMutex,ms_pMutex);
89 
90  FEASSERT(ms_pMutex);
91 
92 // if(--ms_mutexCount == 0)
93  if(!(feAsmSwapIncr(&ms_mutexCount,-1)-1))
94  {
95  //* NOTE marked for death
96 // delete ms_pMutex;
97 // ms_pMutex=NULL;
98  }
99  }
100 
101 virtual RecursiveMutex* fe_class_thread_mutex(void) const
102  {
103 // feLog("%p trueClassSafe<%s>::fe_class_thread_mutex"
104 // " %d %p %p\n",
105 // this,FE_TYPESTRING(T).c_str(),
106 // ms_mutexCount,&ms_pMutex,ms_pMutex);
107  return ms_pMutex;
108  }
109 
110  private:
111 static FE_DL_PUBLIC I32 ms_mutexCount;
112 static FE_DL_PUBLIC RecursiveMutex* ms_pMutex;
113 #else
114 virtual RecursiveMutex* fe_class_thread_mutex(void) const
115  {
116 // feLog("%p fe_class_thread_mutex %p\n",this,&ms_mutex);
117  return &ms_mutex;
118  }
119  private:
120 static FE_DL_PUBLIC RecursiveMutex ms_mutex;
121 #endif
122 };
123 
124 template <typename T>
125 class FE_DL_EXPORT trueObjectSafe : public SafeBase
126 {
127  public:
128  class FE_DL_PUBLIC SafeGuard
129  {
130  public:
131  SafeGuard(RecursiveMutex *mutex,BWORD a_truly=TRUE):
132  m_guard(*mutex,FALSE,a_truly) {}
133  void lock(void) { m_guard.lock(); }
134  void unlock(void) { m_guard.unlock(); }
135 
136  RecursiveMutex::Guard& guard(void)
137  { return m_guard; }
138  private:
139  RecursiveMutex::Guard m_guard;
140  };
141 
142  trueObjectSafe(void)
143  {
144  //* force initialization
145  SafeGuard guard(&m_fe_mutex);
146  }
147 virtual ~trueObjectSafe(void) {}
148 
149 virtual RecursiveMutex *fe_thread_mutex(void) const
150  {
151  /* cast away const here so that ObjectSafe can be used on const
152  accessors that would otherwise be vulnerable to non-const
153  mutators */
154  return const_cast<RecursiveMutex*>(&m_fe_mutex);
155  }
156 
157  private:
158  RecursiveMutex m_fe_mutex;
159 };
160 
161 template <typename T>
162 class FE_DL_EXPORT trueNotSafe : public SafeBase
163 {
164  public:
165  class FE_DL_PUBLIC SafeGuard
166  {
167  public:
168  SafeGuard(RecursiveMutex *mutex,BWORD a_truly=TRUE) {}
169  void lock(void) {}
170  void unlock(void) {}
171  };
172 
173  trueNotSafe(void) {}
174 virtual ~trueNotSafe(void) {}
175 
176 virtual RecursiveMutex* fe_thread_mutex(void) const { return NULL; }
177 };
178 
179 template <typename T>
180 class FE_DL_EXPORT trueNotClassSafe : public ClassSafeBase
181 {
182  public:
183  class FE_DL_PUBLIC SafeGuard
184  {
185  public:
186  SafeGuard(RecursiveMutex *mutex,BWORD a_truly=TRUE) {}
187  void lock(void) {}
188  void unlock(void) {}
189  };
190 
191  trueNotClassSafe(void) {}
192 virtual ~trueNotClassSafe(void) {}
193 
194 virtual RecursiveMutex* fe_class_thread_mutex(void) const { return NULL; }
195 };
196 
197 #if FE_SAFE_COUNTED_MUTEX
198 template<typename T>
199 FE_DL_PUBLIC RecursiveMutex* trueClassSafe<T>::ms_pMutex=NULL;
200 template<typename T>
201 FE_DL_PUBLIC I32 trueClassSafe<T>::ms_mutexCount=0;
202 #else
203 template<typename T>
204 FE_DL_PUBLIC RecursiveMutex trueClassSafe<T>::ms_mutex;
205 #endif
206 
207 class FE_DL_EXPORT GlobalHolder:
208  public trueClassSafe<GlobalHolder> {};
209 
210 #ifndef FE_DISABLE_THREAD_SAFE
211 /** Class level locking for thread safety
212  */
213 template<typename T> class FE_DL_EXPORT ClassSafe:
214  public trueClassSafe<T> {};
215 /// Object level locking for thread safety
216 template<typename T> class FE_DL_EXPORT ObjectSafe:
217  public trueObjectSafe<T> {};
218 /// No locking for thread safety
219 template<typename T> class FE_DL_EXPORT NotSafe:
220  public trueNotSafe<T> {};
221 #else
222 /// Class level locking for thread safety
223 template<typename T> class FE_DL_EXPORT ClassSafe:
224  public trueNotClassSafe<T> {};
225 /// Object level locking for thread safety
226 template<typename T> class FE_DL_EXPORT ObjectSafe:
227  public trueNotSafe<T> {};
228 /// No locking for thread safety
229 template<typename T> class FE_DL_EXPORT NotSafe:
230  public trueNotSafe<T> {};
231 #endif
232 
233 } /* namespace */
234 
235 #endif /* __core_Safe_h__ */
Object level locking for thread safety.
Definition: Safe.h:216
Class level locking for thread safety.
Definition: Safe.h:213
No locking for thread safety.
Definition: Safe.h:219
kernel
Definition: namespace.dox:3