vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MTLock.h
Go to the documentation of this file.
1 
9 #ifndef MTLOCK_H
10 #define MTLOCK_H
11 
12 
13 #ifdef WIN32
14  #include <windows.h>
15 
16  //#define USE_CRITICAL_SECTIONS
17  // Critical sections are faster, but cannot be used to synchronize activity
18  // across different processes/DLLs.
19 #endif
20 
21 #include <map>
22 
23 
24 namespace vrecko {
25 
26 
27 #ifdef VRECKO_LIBRARY
28  #define MTLOCK_IMP_EXP __declspec(dllexport)
29 #else
30  #define MTLOCK_IMP_EXP __declspec(dllimport)
31 #endif
32 
33 
34 
35 #if 0
36 
37 
38  // "COPTex" version.
39  // As fast as a critical section, but can be used for inter-process synchronization.
40  // http://www.microsoft.com/msj/0198/win32textfigs.htm#fig2
41  class MTLOCK_IMP_EXP MTLock {
42  public:
43  MTLock();
44  ~MTLock();
45 
46  bool lock();
47  void unlock();
48 
49  protected:
50 
51  void SetSpinCount(DWORD dwSpinCount);
52  BOOL TryEnter();
53 
54  typedef struct {
55  volatile DWORD m_dwSpinCount;
56  volatile long m_lLockCount;
57  volatile DWORD m_dwThreadId;
58  volatile long m_lRecurseCount;
59  } SHAREDINFO, *PSHAREDINFO;
60 
61  BOOL m_fUniprocessorHost;
62  HANDLE m_hevt;
63  HANDLE m_hfm;
64  volatile PSHAREDINFO m_pSharedInfo;
65 
66  BOOL CommonConstructor(PVOID pszName, BOOL fUnicode, DWORD dwSpinCount);
67  };
68 
69  typedef MTLock MTLockSingleProcess;
70 
71 #else
72 
73 
87 public:
88  MTLock();
89  ~MTLock();
90 
91  bool lock();
92  void unlock();
93 
95  HANDLE getHandle() const { return mutex; }
96 
97 protected:
98 
99 #ifdef WIN32
100  HANDLE mutex;
101 #else
102  pthread_mutex_t *mutex;
103 #endif
104 };
105 
106 
109 public:
110  MTAutoLock(MTLock *lockToLock) { theLock = lockToLock; lockToLock->lock(); };
111  ~MTAutoLock() { theLock->unlock(); }
112 protected:
114 };
115 
116 #ifdef WIN32
117 
119  public:
122 
123  bool lock();
124  void unlock();
125 
126  protected:
127  CRITICAL_SECTION criticalSection;
128  };
129 #else
131 #endif
132 
133 
134 #endif
135 
136 
160 {
161 protected:
162  HANDLE m_Access;
165  HANDLE m_CanRead;
166  HANDLE m_CanWrite;
167 
168 public:
169  MTReadWriteLock();
170  ~MTReadWriteLock();
171 
172  bool lockRead( DWORD Timeout = INFINITE );
173  bool lockWrite( DWORD Timeout = INFINITE );
174  void unlockRead( DWORD Timeout = INFINITE );
175  void unlockWrite( DWORD Timeout = INFINITE );
176 };
177 
178 
196  struct KThreadInfo {
197  int ReadCount;
198  int WriteCount;
199 
200  bool IsReader() { return ReadCount > 0; };
201  bool IsWriter() { return WriteCount > 0; };
202  };
203 
204  typedef std::map<DWORD, KThreadInfo> KThreadMap;
205  KThreadMap m_Threads;
206 
207  // Number of reader threads;
208  // Note: writer threads are not reader threads, even if they have read locks
209  int m_TotalReaderThreads;
210  int m_TotalWriterThreads; // current writer + waiting writers
211 
212  HANDLE m_Access;
213  HANDLE m_WriterMutex;
214  HANDLE m_CanRead;
215  HANDLE m_CanWrite;
216 
217  void incReaders()
218  {
219  ++m_TotalReaderThreads;
220  ResetEvent(m_CanWrite);
221  };
222 
223  void decReaders()
224  {
225  if (--m_TotalReaderThreads == 0)
226  SetEvent(m_CanWrite);
227  };
228 
229  void incWriters()
230  {
231  ++m_TotalWriterThreads;
232  ResetEvent(m_CanRead);
233  };
234 
235  void decWriters()
236  {
237  if (--m_TotalWriterThreads == 0)
238  SetEvent(m_CanRead);
239  };
240 
241 public:
244 
245  bool lockRead( DWORD Timeout = INFINITE );
246  bool lockWrite( DWORD Timeout = INFINITE );
247  void unlockRead( DWORD Timeout = INFINITE );
248  void unlockWrite( DWORD Timeout = INFINITE );
249 
250 };
251 
252 
253 // Design by Vit Kovalcik.
254 // Lock with two priorities. The higher one will not starve.
255 // Only a single thread can acquire the lock (i.e. no simultaneous high + low threads).
256 // WARNING - LIMITATION: The high priority part can be used only in a single thread.
257 // Usage in two or more threads will result in an unexpected behaviour.
259 protected:
261  HANDLE m_Access;
263 public:
266 
267  // WARNING: lockHigh()/unlockHigh() sequence can be used only in one thread (at the same time)
268  bool lockHigh();
269  void unlockHigh();
270 
271  bool lockLow();
272  void unlockLow();
273 };
274 
275 
276 };
277 
278 #endif