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.

616 lines
13 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File:
  7. //
  8. // Contents:
  9. //
  10. // History: 12-09-97 HueiWang
  11. //
  12. //---------------------------------------------------------------------------
  13. #ifndef __LS_LOCKS_H
  14. #define __LS_LOCKS_H
  15. #include <windows.h>
  16. #include "assert.h"
  17. extern BOOL g_bLockValid;
  18. #define ARRAY_COUNT(a) sizeof(a) / sizeof(a[0])
  19. typedef enum { WRITER_LOCK, READER_LOCK, NO_LOCK } RWLOCK_TYPE;
  20. //-------------------------------------------------------------------------
  21. template <int init_count, int max_count>
  22. class CTSemaphore {
  23. private:
  24. HANDLE m_semaphore;
  25. public:
  26. CTSemaphore() : m_semaphore(NULL)
  27. {
  28. m_semaphore=CreateSemaphore(NULL, init_count, max_count, NULL);
  29. assert(m_semaphore != NULL);
  30. }
  31. ~CTSemaphore()
  32. {
  33. if(m_semaphore)
  34. CloseHandle(m_semaphore);
  35. }
  36. DWORD Acquire(int WaitTime=INFINITE, BOOL bAlertable=FALSE)
  37. {
  38. if(m_semaphore == NULL)
  39. {
  40. SetLastError(ERROR_INVALID_PARAMETER);
  41. return FALSE;
  42. }
  43. return WaitForSingleObjectEx(m_semaphore, WaitTime, bAlertable);
  44. }
  45. BOOL
  46. AcquireEx(
  47. HANDLE hHandle,
  48. int dwWaitTime=INFINITE,
  49. BOOL bAlertable=FALSE
  50. )
  51. /*++
  52. --*/
  53. {
  54. BOOL bSuccess = TRUE;
  55. DWORD dwStatus;
  56. HANDLE hHandles[] = {m_semaphore, hHandle};
  57. if(hHandle == NULL || hHandle == INVALID_HANDLE_VALUE)
  58. {
  59. SetLastError(ERROR_INVALID_PARAMETER);
  60. bSuccess = FALSE;
  61. }
  62. else
  63. {
  64. if(m_semaphore == NULL || hHandle == NULL)
  65. {
  66. SetLastError(ERROR_INVALID_PARAMETER);
  67. return FALSE;
  68. }
  69. dwStatus = WaitForMultipleObjectsEx(
  70. sizeof(hHandles)/sizeof(hHandles[0]),
  71. hHandles,
  72. FALSE,
  73. dwWaitTime,
  74. bAlertable
  75. );
  76. if(dwStatus != WAIT_OBJECT_0)
  77. {
  78. bSuccess = FALSE;
  79. }
  80. }
  81. return bSuccess;
  82. }
  83. BOOL Release(long count=1)
  84. {
  85. if(m_semaphore == NULL)
  86. {
  87. SetLastError(ERROR_INVALID_PARAMETER);
  88. return FALSE;
  89. }
  90. return ReleaseSemaphore(m_semaphore, count, NULL);
  91. }
  92. BOOL IsGood()
  93. {
  94. return m_semaphore != NULL;
  95. }
  96. };
  97. //-------------------------------------------------------------------------
  98. class CCriticalSection {
  99. CRITICAL_SECTION m_CS;
  100. BOOL m_bGood;
  101. public:
  102. CCriticalSection(
  103. DWORD dwSpinCount = 4000 // see InitializeCriticalSection...
  104. ) : m_bGood(TRUE)
  105. {
  106. __try {
  107. if(!InitializeCriticalSectionAndSpinCount(&m_CS, dwSpinCount))
  108. m_bGood = FALSE;
  109. }
  110. __except(EXCEPTION_EXECUTE_HANDLER)
  111. {
  112. SetLastError(GetExceptionCode());
  113. m_bGood = FALSE;
  114. }
  115. }
  116. ~CCriticalSection()
  117. {
  118. if(IsGood() == TRUE)
  119. {
  120. DeleteCriticalSection(&m_CS);
  121. }
  122. }
  123. BOOL
  124. IsGood() { return m_bGood; }
  125. void Lock()
  126. {
  127. if(IsGood() == TRUE)
  128. {
  129. EnterCriticalSection(&m_CS);
  130. }
  131. }
  132. void UnLock()
  133. {
  134. if(IsGood() == TRUE)
  135. {
  136. LeaveCriticalSection(&m_CS);
  137. }
  138. }
  139. BOOL TryLock()
  140. {
  141. if(IsGood() == TRUE)
  142. {
  143. return TryEnterCriticalSection(&m_CS);
  144. }
  145. else
  146. return FALSE;
  147. }
  148. };
  149. //--------------------------------------------------------------------------
  150. class CCriticalSectionLocker {
  151. public:
  152. CCriticalSectionLocker( CCriticalSection& m ) : m_cs(m)
  153. {
  154. m.Lock();
  155. }
  156. ~CCriticalSectionLocker()
  157. {
  158. m_cs.UnLock();
  159. }
  160. private:
  161. CCriticalSection& m_cs;
  162. };
  163. //-----------------------------------------------------------
  164. class CSafeCounter {
  165. private:
  166. //CCriticalSection m_cs;
  167. long m_Counter;
  168. //inline void
  169. //Lock()
  170. //{
  171. // m_cs.Lock();
  172. //}
  173. //inline void
  174. //Unlock()
  175. //{
  176. // m_cs.UnLock();
  177. //}
  178. public:
  179. CSafeCounter(
  180. long init_value=0
  181. ) :
  182. m_Counter(init_value)
  183. /*++
  184. --*/
  185. {
  186. }
  187. ~CSafeCounter()
  188. {
  189. }
  190. operator+=(long dwValue)
  191. {
  192. long dwNewValue;
  193. //Lock();
  194. //dwNewValue = (m_Counter += dwValue);
  195. //Unlock();
  196. //return dwNewValue;
  197. dwNewValue = InterlockedExchangeAdd( &m_Counter, dwValue );
  198. return dwNewValue += dwValue;
  199. }
  200. operator-=(long dwValue)
  201. {
  202. long dwNewValue;
  203. //Lock();
  204. //dwNewValue = (m_Counter -= dwValue);
  205. //Unlock();
  206. //return dwNewValue;
  207. dwNewValue = InterlockedExchangeAdd( &m_Counter, -dwValue );
  208. return dwNewValue -= dwValue;
  209. }
  210. operator++()
  211. {
  212. //long dwValue;
  213. //Lock();
  214. //dwValue = ++m_Counter;
  215. //Unlock();
  216. //return dwValue;
  217. return InterlockedIncrement(&m_Counter);
  218. }
  219. operator++(int)
  220. {
  221. //long dwValue;
  222. //Lock();
  223. //dwValue = m_Counter++;
  224. //Unlock();
  225. //return dwValue;
  226. long lValue;
  227. lValue = InterlockedIncrement(&m_Counter);
  228. return --lValue;
  229. }
  230. operator--()
  231. {
  232. //long dwValue;
  233. //Lock();
  234. //dwValue = --m_Counter;
  235. //Unlock();
  236. //return dwValue;
  237. return InterlockedDecrement(&m_Counter);
  238. }
  239. operator--(int)
  240. {
  241. //long dwValue;
  242. //Lock();
  243. //dwValue = m_Counter--;
  244. //Unlock();
  245. //return dwValue;
  246. long lValue;
  247. lValue = InterlockedDecrement(&m_Counter);
  248. return ++lValue;
  249. }
  250. operator long()
  251. {
  252. //long lValue;
  253. //Lock();
  254. //lValue = m_Counter;
  255. //Unlock();
  256. //return lValue;
  257. return InterlockedExchange(&m_Counter, m_Counter);
  258. }
  259. //operator DWORD()
  260. //{
  261. // long dwValue;
  262. // Lock();
  263. // dwValue = m_Counter;
  264. // Unlock();
  265. // return dwValue;
  266. //}
  267. operator=(const long dwValue)
  268. {
  269. //Lock();
  270. //m_Counter = dwValue;
  271. //Unlock();
  272. //return dwValue;
  273. InterlockedExchange(&m_Counter, dwValue);
  274. return dwValue;
  275. }
  276. };
  277. //-------------------------------------------------------------------------
  278. // HueiWang 12/23/97 need more testing...
  279. class CRWLock
  280. {
  281. private:
  282. HANDLE hMutex;
  283. HANDLE hWriterMutex;
  284. HANDLE hReaderEvent;
  285. long iReadCount;
  286. long iWriteCount;
  287. long iReadEntry;
  288. long iWriteEntry;
  289. public:
  290. CRWLock()
  291. {
  292. BOOL bSuccess=Init();
  293. assert(bSuccess == TRUE);
  294. }
  295. ~CRWLock()
  296. {
  297. Cleanup();
  298. }
  299. //-----------------------------------------------------------
  300. BOOL
  301. Init()
  302. {
  303. hReaderEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
  304. hMutex = CreateEvent(NULL,FALSE,TRUE,NULL);
  305. hWriterMutex = CreateMutex(NULL,FALSE,NULL);
  306. if(!hReaderEvent || !hMutex || !hWriterMutex)
  307. return FALSE;
  308. iReadCount = -1;
  309. iWriteCount = -1;
  310. iReadEntry = 0;
  311. iWriteEntry = 0;
  312. return (TRUE);
  313. }
  314. //-----------------------------------------------------------
  315. void
  316. Cleanup()
  317. {
  318. if(hReaderEvent != NULL)
  319. {
  320. CloseHandle(hReaderEvent);
  321. }
  322. if(hMutex != NULL)
  323. {
  324. CloseHandle(hMutex);
  325. }
  326. if(hWriterMutex != NULL)
  327. {
  328. CloseHandle(hWriterMutex);
  329. }
  330. iReadCount = -1;
  331. iWriteCount = -1;
  332. iReadEntry = 0;
  333. iWriteEntry = 0;
  334. }
  335. //-----------------------------------------------------------
  336. void
  337. Acquire(
  338. RWLOCK_TYPE lockType
  339. )
  340. /*++
  341. ++*/
  342. {
  343. if (lockType == WRITER_LOCK)
  344. {
  345. InterlockedIncrement(&iWriteCount);
  346. if(hWriterMutex != NULL)
  347. {
  348. WaitForSingleObject(hWriterMutex,INFINITE);
  349. }
  350. if(hMutex != NULL)
  351. {
  352. WaitForSingleObject(hMutex, INFINITE);
  353. }
  354. assert(InterlockedIncrement(&iWriteEntry) == 1);
  355. assert(InterlockedExchange(&iReadEntry, iReadEntry) == 0);
  356. }
  357. else
  358. {
  359. if(hReaderEvent != NULL)
  360. {
  361. if (InterlockedIncrement(&iReadCount) == 0)
  362. {
  363. if(hMutex != NULL)
  364. {
  365. WaitForSingleObject(hMutex, INFINITE);
  366. }
  367. SetEvent(hReaderEvent);
  368. }
  369. WaitForSingleObject(hReaderEvent,INFINITE);
  370. }
  371. InterlockedIncrement(&iReadEntry);
  372. assert(InterlockedExchange(&iWriteEntry, iWriteEntry) == 0);
  373. }
  374. }
  375. //-----------------------------------------------------------
  376. void
  377. Release(
  378. RWLOCK_TYPE lockType
  379. )
  380. /*++
  381. ++*/
  382. {
  383. if (lockType == WRITER_LOCK)
  384. {
  385. InterlockedDecrement(&iWriteEntry);
  386. InterlockedDecrement(&iWriteCount);
  387. if(hMutex != NULL)
  388. {
  389. SetEvent(hMutex);
  390. }
  391. if(hWriterMutex != NULL)
  392. {
  393. ReleaseMutex(hWriterMutex);
  394. }
  395. }
  396. else if(lockType == READER_LOCK)
  397. {
  398. InterlockedDecrement(&iReadEntry);
  399. if (InterlockedDecrement(&iReadCount) < 0)
  400. {
  401. if(hReaderEvent != NULL)
  402. {
  403. ResetEvent(hReaderEvent);
  404. }
  405. if(hMutex != NULL)
  406. {
  407. SetEvent(hMutex);
  408. }
  409. }
  410. }
  411. }
  412. long GetReadCount()
  413. {
  414. return iReadCount+1;
  415. }
  416. long GetWriteCount()
  417. {
  418. return iWriteCount+1;
  419. }
  420. };
  421. //---------------------------------------------------------------------
  422. //
  423. //
  424. class CCMutex {
  425. public:
  426. HANDLE hMutex;
  427. CCMutex() : hMutex(NULL) {
  428. hMutex=CreateMutex(NULL, FALSE, NULL);
  429. }
  430. ~CCMutex() {
  431. if(hMutex != NULL)
  432. {
  433. CloseHandle(hMutex);
  434. }
  435. }
  436. DWORD Lock(
  437. DWORD dwWaitTime=INFINITE,
  438. BOOL bAlertable=FALSE
  439. )
  440. {
  441. if(hMutex != NULL)
  442. {
  443. return WaitForSingleObjectEx(
  444. hMutex,
  445. dwWaitTime,
  446. bAlertable);
  447. }
  448. else
  449. {
  450. return WAIT_FAILED;
  451. }
  452. }
  453. BOOL Unlock() {
  454. if(hMutex != NULL)
  455. {
  456. return ReleaseMutex(hMutex);
  457. }
  458. else
  459. return FALSE;
  460. }
  461. };
  462. //---------------------------------------------------------------------------------
  463. class CCEvent {
  464. BOOL bManual;
  465. public:
  466. HANDLE hEvent;
  467. CCEvent(
  468. BOOL bManual,
  469. BOOL bInitState) :
  470. hEvent(NULL),
  471. bManual(bManual)
  472. {
  473. hEvent=CreateEvent(
  474. NULL,
  475. bManual,
  476. bInitState,
  477. NULL);
  478. g_bLockValid = TRUE;
  479. }
  480. ~CCEvent() {
  481. if(hEvent)
  482. {
  483. CloseHandle(hEvent);
  484. }
  485. g_bLockValid = FALSE;
  486. }
  487. DWORD Lock( DWORD dwWaitTime=INFINITE,
  488. BOOL bAlertable=FALSE)
  489. {
  490. if(hEvent)
  491. {
  492. return WaitForSingleObjectEx(
  493. hEvent,
  494. dwWaitTime,
  495. bAlertable);
  496. }
  497. else
  498. return WAIT_FAILED;
  499. }
  500. BOOL SetEvent() {
  501. if(hEvent)
  502. {
  503. return ::SetEvent(hEvent);
  504. }
  505. else
  506. return FALSE;
  507. }
  508. BOOL ResetEvent() {
  509. if(hEvent)
  510. {
  511. return ::ResetEvent(hEvent);
  512. }
  513. else
  514. return FALSE;
  515. }
  516. BOOL PulseEvent() {
  517. if(hEvent)
  518. {
  519. return ::PulseEvent(hEvent);
  520. }
  521. else
  522. return FALSE;
  523. }
  524. BOOL IsManual() {
  525. return bManual;
  526. }
  527. };
  528. #endif