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.

155 lines
3.3 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // Guard.h
  8. //
  9. // SYNOPSIS
  10. //
  11. // Contains classes for implementing scoped-locking using Win32 criticial
  12. // sections.
  13. //
  14. // MODIFICATION HISTORY
  15. //
  16. // 07/09/1997 Original version.
  17. // 05/12/1999 Use a spin lock.
  18. // 07/20/1999 Use TryEnterCriticalSection/SwitchToThread
  19. //
  20. ///////////////////////////////////////////////////////////////////////////////
  21. #ifndef _GUARD_H_
  22. #define _GUARD_H_
  23. #if _MSC_VER >= 1000
  24. #pragma once
  25. #endif
  26. #include <nocopy.h>
  27. ///////////////////////////////////////////////////////////////////////////////
  28. //
  29. // CLASS
  30. //
  31. // Guard<class T>
  32. //
  33. // DESCRIPTION
  34. //
  35. // Implements a scoped lock of type T. T must define operations Lock() and
  36. // Unlock(). The lock is acquired in the constructor and released in the
  37. // destructor.
  38. //
  39. ///////////////////////////////////////////////////////////////////////////////
  40. template<class T>
  41. class Guard : NonCopyable
  42. {
  43. public:
  44. explicit Guard(const T& lock) throw()
  45. : m_prisoner(const_cast<T&>(lock))
  46. {
  47. m_prisoner.Lock();
  48. }
  49. ~Guard() throw()
  50. {
  51. m_prisoner.Unlock();
  52. }
  53. protected:
  54. T& m_prisoner;
  55. };
  56. //////////
  57. //
  58. // Macro used to declare a scoped lock inside a method belonging to a
  59. // subclass of CComObjectRootEx<CComMultiThreadModel>. Useful for free-
  60. // threaded ATL components.
  61. //
  62. //////////
  63. #define _com_serialize \
  64. Guard< CComObjectRootEx<CComMultiThreadModel> > __GUARD__(*this);
  65. ///////////////////////////////////////////////////////////////////////////////
  66. //
  67. // STRUCT
  68. //
  69. // CCriticalSection
  70. //
  71. // DESCRIPTION
  72. //
  73. // Simple wrapper around a Win32 critical section. Suitable for use with
  74. // the Guard class above.
  75. //
  76. ///////////////////////////////////////////////////////////////////////////////
  77. struct CCriticalSection : CRITICAL_SECTION
  78. {
  79. public:
  80. CCriticalSection()
  81. {
  82. InitializeCriticalSection(this);
  83. }
  84. ~CCriticalSection()
  85. {
  86. DeleteCriticalSection(this);
  87. }
  88. void Lock()
  89. {
  90. int tries = 0;
  91. while (!TryEnterCriticalSection(this))
  92. {
  93. if (++tries < 100)
  94. {
  95. SwitchToThread();
  96. }
  97. else
  98. {
  99. EnterCriticalSection(this);
  100. break;
  101. }
  102. }
  103. }
  104. void Unlock()
  105. {
  106. LeaveCriticalSection(this);
  107. }
  108. };
  109. ///////////////////////////////////////////////////////////////////////////////
  110. //
  111. // CLASS
  112. //
  113. // Guardable
  114. //
  115. // DESCRIPTION
  116. //
  117. // Base class for objects that need to synchronize access. Do not use this
  118. // for free-threaded COM objects since this functionality already exists in
  119. // CComObjectRootEx<CComMultiThreadModel>.
  120. //
  121. ///////////////////////////////////////////////////////////////////////////////
  122. class Guardable
  123. {
  124. public:
  125. void Lock() const { m_monitor.Lock(); }
  126. void Unlock() const { m_monitor.Unlock(); }
  127. protected:
  128. mutable CCriticalSection m_monitor;
  129. };
  130. //////////
  131. //
  132. // Macro used to declare a scoped lock inside a method belonging to a
  133. // subclass of Guardable.
  134. //
  135. //////////
  136. #define _serialize Guard<Guardable> __GUARD__(*this);
  137. #endif // _GUARD_H_