Free Electron
SafeShared.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_SafeShared_h__
8 #define __core_SafeShared_h__
9 
10 // TODO prefix methods as safe*, like safeUnlock()
11 
12 namespace fe
13 {
14 
15 class SafeSharedCore
16 {
17  public:
18 virtual ~SafeSharedCore(void) {}
19 
20 virtual void safeLock(void) const =0;
21 virtual void safeUnlock(void) const =0;
22 virtual bool safeTryLock(void) const =0;
23 
24 virtual void safeLockShared(void) const =0;
25 virtual void safeUnlockShared(void) const =0;
26 virtual bool safeTryLockShared(void) const =0;
27 
28 };
29 
30 class SafeSharedBase: public SafeSharedCore
31 {
32  public:
33 virtual ~SafeSharedBase(void) {}
34  // returns a pointer because NotSafeShared does not require a mutex
35 virtual Mutex *fe_thread_mutex(void) const =0;
36 };
37 
38 class ClassSafeSharedBase: public SafeSharedCore
39 {
40  public:
41 virtual ~ClassSafeSharedBase(void) {}
42  // returns a pointer because NotSafeShared does not require a mutex
43 virtual Mutex *fe_class_thread_mutex(void) const =0;
44 };
45 
46 template <typename T>
47 class FE_DL_EXPORT trueClassSafeShared: public ClassSafeSharedBase
48 {
49  public:
50 
51 virtual void safeLock(void) const
52  { fe_class_thread_mutex()->lock(); }
53 virtual void safeUnlock(void) const
54  { fe_class_thread_mutex()->unlock(); }
55 virtual bool safeTryLock(void) const
56  { return fe_class_thread_mutex()->tryLock(); }
57 
58 virtual void safeLockShared(void) const
59  { fe_class_thread_mutex()->lockReadOnly(); }
60 virtual void safeUnlockShared(void) const
61  { fe_class_thread_mutex()->unlockReadOnly(); }
62 virtual bool safeTryLockShared(void) const
63  { return fe_class_thread_mutex()->tryLockReadOnly(); }
64 
65 #if FE_SAFE_COUNTED_MUTEX
66 
67  trueClassSafeShared(void)
68  {
69 // feLog("%p trueClassSafeShared<%s> %d %p\n",
70 // this,FE_TYPESTRING(T).c_str(),
71 // ms_mutexCount,&ms_pMutex);
72 
73 // if(ms_mutexCount++ == 0)
74  if(!feAsmSwapIncr(&ms_mutexCount,1) && !ms_pMutex)
75  {
76  ms_pMutex=new Mutex;
77  Memory::markForDeath(ms_pMutex,&ms_mutexCount);
78  }
79  FEASSERT(ms_pMutex);
80  }
81 
82 virtual ~trueClassSafeShared(void)
83  {
84 // feLog("%p ~trueClassSafeShared<%s> %d %p\n",
85 // this,FE_TYPESTRING(T).c_str(),
86 // ms_mutexCount,&ms_pMutex);
87 
88  FEASSERT(ms_pMutex);
89 
90 // if(--ms_mutexCount == 0)
91  if(!(feAsmSwapIncr(&ms_mutexCount,-1)-1))
92  {
93  //* NOTE marked for death
94 // delete ms_pMutex;
95 // ms_pMutex=NULL;
96  }
97  }
98 
99 virtual Mutex* fe_class_thread_mutex(void) const
100  {
101 // feLog("%p fe_class_thread_mutex %d %p %p\n",
102 // this,ms_mutexCount,&ms_pMutex,ms_pMutex);
103  return ms_pMutex;
104  }
105 
106 
107  private:
108 static FE_DL_PUBLIC I32 ms_mutexCount;
109 static FE_DL_PUBLIC Mutex* ms_pMutex;
110 
111 #else
112 
113 virtual Mutex* fe_class_thread_mutex(void) const
114  {
115 // feLog("%p fe_class_thread_mutex %p\n",this,&ms_mutex);
116  return &ms_mutex;
117  }
118 
119  private:
120 static FE_DL_PUBLIC Mutex ms_mutex;
121 
122 #endif
123 };
124 
125 template <typename T>
126 class FE_DL_EXPORT trueObjectSafeShared : public SafeSharedBase
127 {
128  public:
129 
130  trueObjectSafeShared(void)
131  {
132  //* force initialization
133  safeLock();
134  safeUnlock();
135  }
136 virtual ~trueObjectSafeShared(void) {}
137 
138 virtual Mutex *fe_thread_mutex(void) const
139  {
140  /* cast away const here so that ObjectSafeShared can be
141  used on const accessors that would otherwise be vulnerable
142  to non-const mutators */
143  return const_cast<Mutex*>(&m_fe_mutex);
144  }
145 
146 virtual void safeLock(void) const
147  { fe_thread_mutex()->lock(); }
148 virtual void safeUnlock(void) const
149  { fe_thread_mutex()->unlock(); }
150 virtual bool safeTryLock(void) const
151  { return fe_thread_mutex()->tryLock(); }
152 
153 virtual void safeLockShared(void) const
154  { fe_thread_mutex()->lockReadOnly(); }
155 virtual void safeUnlockShared(void) const
156  { fe_thread_mutex()->unlockReadOnly(); }
157 virtual bool safeTryLockShared(void) const
158  { return fe_thread_mutex()->tryLockReadOnly(); }
159 
160  private:
161  Mutex m_fe_mutex;
162 };
163 
164 template <typename T>
165 class FE_DL_EXPORT trueClassNotSafeShared : public ClassSafeSharedBase
166 {
167  public:
168  trueClassNotSafeShared(void) {}
169 virtual ~trueClassNotSafeShared(void) {}
170 
171 virtual Mutex* fe_class_thread_mutex(void) const { return NULL; }
172 
173 virtual void safeLock(void) const {}
174 virtual void safeUnlock(void) const {}
175 virtual bool safeTryLock(void) const { return false; }
176 
177 virtual void safeLockShared(void) const {}
178 virtual void safeUnlockShared(void) const {}
179 virtual bool safeTryLockShared(void) const { return false; }
180 
181 };
182 
183 template <typename T>
184 class FE_DL_EXPORT trueNotSafeShared : public SafeSharedBase
185 {
186  public:
187  trueNotSafeShared(void) {}
188 virtual ~trueNotSafeShared(void) {}
189 
190 virtual Mutex* fe_thread_mutex(void) const { return NULL; }
191 
192 virtual void safeLock(void) const {}
193 virtual void safeUnlock(void) const {}
194 virtual bool safeTryLock(void) const { return false; }
195 
196 virtual void safeLockShared(void) const {}
197 virtual void safeUnlockShared(void) const {}
198 virtual bool safeTryLockShared(void) const { return false; }
199 
200 };
201 
202 #if FE_SAFE_COUNTED_MUTEX
203 template<typename T>
204 FE_DL_PUBLIC Mutex* trueClassSafeShared<T>::ms_pMutex=NULL;
205 template<typename T>
206 FE_DL_PUBLIC I32 trueClassSafeShared<T>::ms_mutexCount=0;
207 #else
208 template<typename T>
209 FE_DL_PUBLIC Mutex trueClassSafeShared<T>::ms_mutex;
210 #endif
211 
212 #ifndef FE_DISABLE_THREAD_SAFE
213 /** Class level locking for thread safety
214  */
215 template<typename T>
216 class FE_DL_EXPORT ClassSafeShared:
217  public trueClassSafeShared<T> {};
218 /// Object level locking for thread safety
219 template<typename T>
220 class FE_DL_EXPORT ObjectSafeShared:
221  public trueObjectSafeShared<T> {};
222 /// No locking for thread safety
223 template<typename T>
224 class FE_DL_EXPORT NotSafeShared:
225  public trueNotSafeShared<T> {};
226 #else
227 /// Class level locking for thread safety
228 template<typename T>
229 class FE_DL_EXPORT ClassSafeShared:
230  public trueNotClassSafeShared<T> {};
231 /// Object level locking for thread safety
232 template<typename T>
233 class FE_DL_EXPORT ObjectSafeShared:
234  public trueNotSafeShared<T> {};
235 /// No locking for thread safety
236 template<typename T>
237 class FE_DL_EXPORT NotSafeShared:
238  public trueNotSafeShared<T> {};
239 #endif
240 
241 } /* namespace */
242 
243 #endif /* __core_SafeShared_h__ */
No locking for thread safety.
Definition: SafeShared.h:224
Class level locking for thread safety.
Definition: SafeShared.h:216
kernel
Definition: namespace.dox:3
Object level locking for thread safety.
Definition: SafeShared.h:220