Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

288 lines
6.8 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Filename : Synchro.h
  4. // Purpose : Synchronization objects
  5. //
  6. // Project : Common
  7. // Component:
  8. //
  9. // Author : urib
  10. //
  11. // Log:
  12. // Aug 28 1997 urib Creation.
  13. // Sep 16 1997 urib Add CSyncMutexCatcher
  14. // Nov 13 1997 urib Add interlocked mutex.
  15. // Feb 18 1997 urib Add critical section class to lock C style critical
  16. // sections.(With DovH)
  17. //
  18. ////////////////////////////////////////////////////////////////////////////////
  19. #ifndef SYNCHRO_H
  20. #define SYNCHRO_H
  21. #include "Tracer.h"
  22. #include "Excption.h"
  23. #include "AutoHndl.h"
  24. class ASyncObject;
  25. class CSyncMutex;
  26. class CSyncCriticalSection;
  27. class CSyncOldCriticalSection;
  28. class CSyncInterlockedMutex;
  29. class CSyncMutexCatcher;
  30. ////////////////////////////////////////////////////////////////////////////////
  31. //
  32. // ASyncMutexObject abstract class definition
  33. //
  34. ////////////////////////////////////////////////////////////////////////////////
  35. class ASyncMutexObject
  36. {
  37. public:
  38. virtual void Lock(ULONG ulTimeOut = 60 * 1000) = NULL;
  39. virtual void Unlock() = NULL;
  40. };
  41. ////////////////////////////////////////////////////////////////////////////////
  42. //
  43. // CSyncMutex class definition
  44. //
  45. ////////////////////////////////////////////////////////////////////////////////
  46. class CSyncMutex : public ASyncMutexObject
  47. {
  48. public:
  49. CSyncMutex(
  50. LPSECURITY_ATTRIBUTES lpMutexAttributes = NULL,
  51. BOOL bInitialOwner = FALSE,
  52. LPCTSTR lpName = NULL)
  53. {
  54. m_ahMutex = CreateMutex(lpMutexAttributes, bInitialOwner, lpName);
  55. if(IS_BAD_HANDLE(m_ahMutex))
  56. {
  57. Trace(
  58. elError,
  59. tagError,(
  60. "CSyncMutex:"
  61. "Could not create mutex"));
  62. throw CWin32ErrorException();
  63. }
  64. }
  65. virtual void Lock(ULONG ulTimeOut)
  66. {
  67. DWORD dwWaitResult;
  68. dwWaitResult = WaitForSingleObject(m_ahMutex, ulTimeOut);
  69. if (WAIT_ABANDONED == dwWaitResult)
  70. {
  71. Trace(
  72. elError,
  73. tagError,(
  74. "CSyncMutex:"
  75. "Mutex abandoned"));
  76. }
  77. else if (WAIT_TIMEOUT == dwWaitResult)
  78. {
  79. Trace(
  80. elError,
  81. tagError,(
  82. "CSyncMutex:"
  83. "Timeout"));
  84. throw CWin32ErrorException(ERROR_SEM_TIMEOUT);
  85. }
  86. else if (WAIT_FAILED == dwWaitResult)
  87. {
  88. IS_FAILURE(FALSE);
  89. Trace(
  90. elError,
  91. tagError,(
  92. "CSyncMutex:"
  93. "Wait for single object failed with error %d",
  94. GetLastError()));
  95. throw CWin32ErrorException();
  96. }
  97. Assert(WAIT_OBJECT_0 == dwWaitResult);
  98. }
  99. virtual void Unlock()
  100. {
  101. if (IS_FAILURE(ReleaseMutex(m_ahMutex)))
  102. {
  103. Trace(
  104. elError,
  105. tagError,(
  106. "~CSyncMutex:"
  107. "ReleaseMutex failed"));
  108. }
  109. }
  110. operator HANDLE()
  111. {
  112. return m_ahMutex;
  113. }
  114. protected:
  115. CAutoHandle m_ahMutex;
  116. };
  117. ////////////////////////////////////////////////////////////////////////////////
  118. //
  119. // CSyncCriticalSection class implementation
  120. //
  121. ////////////////////////////////////////////////////////////////////////////////
  122. class ASyncCriticalSection : protected CRITICAL_SECTION, public ASyncMutexObject
  123. {
  124. public:
  125. ~ASyncCriticalSection()
  126. {
  127. DeleteCriticalSection(this);
  128. }
  129. virtual void Lock(ULONG = 0)
  130. {
  131. EnterCriticalSection(this);
  132. }
  133. virtual void Unlock()
  134. {
  135. LeaveCriticalSection(this);
  136. }
  137. };
  138. class CSyncCriticalSection : public ASyncCriticalSection
  139. {
  140. public:
  141. CSyncCriticalSection()
  142. {
  143. Init();
  144. }
  145. private:
  146. void Init()
  147. {
  148. __try
  149. {
  150. InitializeCriticalSection(this);
  151. }
  152. __except(GetExceptionCode() == STATUS_NO_MEMORY)
  153. {
  154. THROW_MEMORY_EXCEPTION();
  155. }
  156. }
  157. };
  158. #if _WIN32_WINNT >= 0x0500
  159. class CSyncCriticalSectionWithSpinCount : public ASyncCriticalSection
  160. {
  161. public:
  162. CSyncCriticalSectionWithSpinCount(ULONG ulSpinCount = 4000)
  163. {
  164. BOOL fRet;
  165. fRet = InitializeCriticalSectionAndSpinCount(this, ulSpinCount);
  166. if (!fRet)
  167. {
  168. THROW_HRESULT_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  169. }
  170. }
  171. };
  172. #endif
  173. ////////////////////////////////////////////////////////////////////////////////
  174. //
  175. // CSyncOldCriticalSection class implementation
  176. //
  177. ////////////////////////////////////////////////////////////////////////////////
  178. class CSyncOldCriticalSection : public ASyncMutexObject
  179. {
  180. public:
  181. CSyncOldCriticalSection(CRITICAL_SECTION* pCriticalSection)
  182. :m_pCriticalSection(pCriticalSection) {}
  183. virtual void Lock(ULONG = 0)
  184. {
  185. EnterCriticalSection(m_pCriticalSection);
  186. }
  187. virtual void Unlock()
  188. {
  189. LeaveCriticalSection(m_pCriticalSection);
  190. }
  191. protected:
  192. CRITICAL_SECTION *m_pCriticalSection;
  193. };
  194. ////////////////////////////////////////////////////////////////////////////////
  195. //
  196. // CSyncInterlockedMutex class definition
  197. //
  198. ////////////////////////////////////////////////////////////////////////////////
  199. class CSyncInterlockedMutex :public ASyncMutexObject
  200. {
  201. public:
  202. CSyncInterlockedMutex()
  203. :m_lMutex(FALSE)
  204. {
  205. }
  206. virtual void Lock(ULONG ulTimeOut = 60 * 1000)
  207. {
  208. ULONG ulWaiting = 0;
  209. LONG lLastValue;
  210. while (lLastValue = InterlockedExchange(&m_lMutex, 1))
  211. {
  212. Sleep(100);
  213. if ((ulWaiting += 100) > ulTimeOut)
  214. {
  215. throw CGenericException(L"TimeOut");
  216. }
  217. }
  218. }
  219. virtual void Unlock()
  220. {
  221. m_lMutex = FALSE;
  222. }
  223. private:
  224. LONG m_lMutex;
  225. };
  226. ////////////////////////////////////////////////////////////////////////////////
  227. //
  228. // CSyncMutexCatcher class implementation
  229. //
  230. ////////////////////////////////////////////////////////////////////////////////
  231. class CSyncMutexCatcher
  232. {
  233. public:
  234. CSyncMutexCatcher(ASyncMutexObject& smo, ULONG ulTimeOut = 60 * 1000)
  235. :m_refSyncObject(smo)
  236. {
  237. m_refSyncObject.Lock();
  238. }
  239. ~CSyncMutexCatcher()
  240. {
  241. m_refSyncObject.Unlock();
  242. }
  243. private:
  244. ASyncMutexObject& m_refSyncObject;
  245. };
  246. #endif // SYNCHRO_H