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.

138 lines
3.0 KiB

  1. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  2. /*--------------------------------------------------
  3. Filename: sync.hpp
  4. Author: B.Rajeev
  5. Purpose: Provides declarations for the MutexLock and
  6. the SemaphoreLock classes (derived from a
  7. generic Lock template class)
  8. --------------------------------------------------*/
  9. #ifndef __SYNC__
  10. #define __SYNC__
  11. // for exception specification
  12. #include "excep.h"
  13. typedef HANDLE Mutex;
  14. typedef HANDLE Semaphore;
  15. #define IMMEDIATE 0
  16. // a generic template class used to build synchronization primitives
  17. // like a Mutex and a Semaphore
  18. template <class SyncObjType>
  19. class Lock
  20. {
  21. protected:
  22. // the sync_obj may be a mutex/semaphore etc.
  23. SyncObjType sync_obj;
  24. // number of locks on the sync obj
  25. LONG num_locks;
  26. // an option that specifies if the held locks must be released
  27. // when the lock is destroyed
  28. BOOL release_on_destroy;
  29. virtual DWORD OpenOperation(DWORD wait_time) = 0 ;
  30. virtual BOOL ReleaseOperation(LONG num_release = 1,
  31. LONG *previous_count = NULL) = 0;
  32. public:
  33. Lock(SyncObjType sync_obj, BOOL release_on_destroy = TRUE) : sync_obj ( sync_obj )
  34. {
  35. num_locks = 0;
  36. Lock::release_on_destroy = release_on_destroy;
  37. }
  38. BOOL GetLock(DWORD wait_time);
  39. UINT UnLock(LONG num_release = 1);
  40. };
  41. template <class SyncObjType>
  42. BOOL Lock<SyncObjType>::GetLock(DWORD wait_time)
  43. {
  44. DWORD wait_result = OpenOperation (wait_time);
  45. if ( wait_result == WAIT_FAILED )
  46. return FALSE;
  47. else if ( wait_result == WAIT_TIMEOUT )
  48. return FALSE;
  49. else
  50. {
  51. num_locks++;
  52. return TRUE;
  53. }
  54. }
  55. template <class SyncObjType>
  56. UINT Lock<SyncObjType>::UnLock(LONG num_release)
  57. {
  58. LONG previous_count;
  59. BOOL release_result =
  60. ReleaseOperation(num_release, &previous_count);
  61. if ( release_result == TRUE )
  62. num_locks -= num_release;
  63. else
  64. throw GeneralException(Snmp_Error, Snmp_Local_Error);
  65. return previous_count;
  66. }
  67. class CriticalSectionLock;
  68. class CriticalSection
  69. {
  70. friend CriticalSectionLock;
  71. private:
  72. CRITICAL_SECTION m_CriticalSection ;
  73. public:
  74. CriticalSection ()
  75. {
  76. InitializeCriticalSection ( &m_CriticalSection ) ;
  77. }
  78. ~CriticalSection()
  79. {
  80. DeleteCriticalSection ( &m_CriticalSection ) ;
  81. }
  82. };
  83. class CriticalSectionLock : public Lock<CriticalSection&>
  84. {
  85. private:
  86. BOOL ReleaseOperation(LONG num_release = 1,
  87. LONG *previous_count = NULL)
  88. {
  89. // both parameters are ignored
  90. LeaveCriticalSection(&sync_obj.m_CriticalSection);
  91. return TRUE;
  92. }
  93. DWORD OpenOperation(DWORD wait_time)
  94. {
  95. EnterCriticalSection(&sync_obj.m_CriticalSection);
  96. return TRUE;
  97. }
  98. public:
  99. CriticalSectionLock(CriticalSection &criticalSection, BOOL release_on_destroy = TRUE)
  100. : Lock<CriticalSection &>(criticalSection, release_on_destroy)
  101. {}
  102. ~CriticalSectionLock(void)
  103. {
  104. if ( (release_on_destroy == TRUE) && (num_locks != 0) )
  105. UnLock(num_locks);
  106. }
  107. };
  108. #endif // __SYNC__