critical_section.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // critical_section.hpp --------------------------------------------------------------//
  2. // Copyright 2010 Vicente J. Botet Escriba
  3. // Copyright 2015 Andrey Semashev
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // See http://www.boost.org/LICENSE_1_0.txt
  6. #ifndef BOOST_DETAIL_WINAPI_CRITICAL_SECTION_HPP
  7. #define BOOST_DETAIL_WINAPI_CRITICAL_SECTION_HPP
  8. #include <boost/detail/winapi/basic_types.hpp>
  9. #include <boost/detail/winapi/detail/cast_ptr.hpp>
  10. #ifdef BOOST_HAS_PRAGMA_ONCE
  11. #pragma once
  12. #endif
  13. #if !defined( BOOST_USE_WINDOWS_H )
  14. extern "C" {
  15. #if !defined( BOOST_WINAPI_IS_MINGW )
  16. struct _RTL_CRITICAL_SECTION;
  17. BOOST_SYMBOL_IMPORT boost::detail::winapi::VOID_ WINAPI
  18. InitializeCriticalSection(::_RTL_CRITICAL_SECTION* lpCriticalSection);
  19. BOOST_SYMBOL_IMPORT boost::detail::winapi::VOID_ WINAPI
  20. EnterCriticalSection(::_RTL_CRITICAL_SECTION* lpCriticalSection);
  21. BOOST_SYMBOL_IMPORT boost::detail::winapi::VOID_ WINAPI
  22. LeaveCriticalSection(::_RTL_CRITICAL_SECTION* lpCriticalSection);
  23. #if BOOST_USE_WINAPI_VERSION >= 0x0403
  24. BOOST_SYMBOL_IMPORT boost::detail::winapi::BOOL_ WINAPI
  25. InitializeCriticalSectionAndSpinCount(
  26. ::_RTL_CRITICAL_SECTION* lpCriticalSection,
  27. boost::detail::winapi::DWORD_ dwSpinCount);
  28. #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
  29. BOOST_SYMBOL_IMPORT boost::detail::winapi::BOOL_ WINAPI
  30. InitializeCriticalSectionEx(
  31. ::_RTL_CRITICAL_SECTION* lpCriticalSection,
  32. boost::detail::winapi::DWORD_ dwSpinCount,
  33. boost::detail::winapi::DWORD_ Flags);
  34. #endif
  35. BOOST_SYMBOL_IMPORT boost::detail::winapi::DWORD_ WINAPI
  36. SetCriticalSectionSpinCount(
  37. ::_RTL_CRITICAL_SECTION* lpCriticalSection,
  38. boost::detail::winapi::DWORD_ dwSpinCount);
  39. #endif
  40. #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_NT4
  41. BOOST_SYMBOL_IMPORT boost::detail::winapi::BOOL_ WINAPI
  42. TryEnterCriticalSection(::_RTL_CRITICAL_SECTION* lpCriticalSection);
  43. #endif
  44. BOOST_SYMBOL_IMPORT boost::detail::winapi::VOID_ WINAPI
  45. DeleteCriticalSection(::_RTL_CRITICAL_SECTION* lpCriticalSection);
  46. #else // defined( BOOST_WINAPI_IS_MINGW )
  47. // MinGW uses a different name for the structure
  48. struct _CRITICAL_SECTION;
  49. BOOST_SYMBOL_IMPORT boost::detail::winapi::VOID_ WINAPI
  50. InitializeCriticalSection(::_CRITICAL_SECTION* lpCriticalSection);
  51. BOOST_SYMBOL_IMPORT boost::detail::winapi::VOID_ WINAPI
  52. EnterCriticalSection(::_CRITICAL_SECTION* lpCriticalSection);
  53. BOOST_SYMBOL_IMPORT boost::detail::winapi::VOID_ WINAPI
  54. LeaveCriticalSection(::_CRITICAL_SECTION* lpCriticalSection);
  55. #if BOOST_USE_WINAPI_VERSION >= 0x0403
  56. BOOST_SYMBOL_IMPORT boost::detail::winapi::BOOL_ WINAPI
  57. InitializeCriticalSectionAndSpinCount(
  58. ::_CRITICAL_SECTION* lpCriticalSection,
  59. boost::detail::winapi::DWORD_ dwSpinCount);
  60. #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
  61. BOOST_SYMBOL_IMPORT boost::detail::winapi::BOOL_ WINAPI
  62. InitializeCriticalSectionEx(
  63. ::_CRITICAL_SECTION* lpCriticalSection,
  64. boost::detail::winapi::DWORD_ dwSpinCount,
  65. boost::detail::winapi::DWORD_ Flags);
  66. #endif
  67. BOOST_SYMBOL_IMPORT boost::detail::winapi::DWORD_ WINAPI
  68. SetCriticalSectionSpinCount(
  69. ::_CRITICAL_SECTION* lpCriticalSection,
  70. boost::detail::winapi::DWORD_ dwSpinCount);
  71. #endif
  72. #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_NT4
  73. BOOST_SYMBOL_IMPORT boost::detail::winapi::BOOL_ WINAPI
  74. TryEnterCriticalSection(::_CRITICAL_SECTION* lpCriticalSection);
  75. #endif
  76. BOOST_SYMBOL_IMPORT boost::detail::winapi::VOID_ WINAPI
  77. DeleteCriticalSection(::_CRITICAL_SECTION* lpCriticalSection);
  78. #endif // defined( BOOST_WINAPI_IS_MINGW )
  79. }
  80. #endif
  81. namespace boost {
  82. namespace detail {
  83. namespace winapi {
  84. struct _RTL_CRITICAL_SECTION_DEBUG;
  85. #pragma pack(push, 8)
  86. typedef struct BOOST_DETAIL_WINAPI_MAY_ALIAS _RTL_CRITICAL_SECTION {
  87. _RTL_CRITICAL_SECTION_DEBUG* DebugInfo;
  88. LONG_ LockCount;
  89. LONG_ RecursionCount;
  90. HANDLE_ OwningThread;
  91. HANDLE_ LockSemaphore;
  92. ULONG_PTR_ SpinCount;
  93. } CRITICAL_SECTION_, *PCRITICAL_SECTION_;
  94. #pragma pack(pop)
  95. BOOST_FORCEINLINE VOID_ InitializeCriticalSection(CRITICAL_SECTION_* lpCriticalSection)
  96. {
  97. ::InitializeCriticalSection(winapi::detail::cast_ptr(lpCriticalSection));
  98. }
  99. BOOST_FORCEINLINE VOID_ EnterCriticalSection(CRITICAL_SECTION_* lpCriticalSection)
  100. {
  101. ::EnterCriticalSection(winapi::detail::cast_ptr(lpCriticalSection));
  102. }
  103. BOOST_FORCEINLINE VOID_ LeaveCriticalSection(CRITICAL_SECTION_* lpCriticalSection)
  104. {
  105. ::LeaveCriticalSection(winapi::detail::cast_ptr(lpCriticalSection));
  106. }
  107. #if BOOST_USE_WINAPI_VERSION >= 0x0403
  108. BOOST_FORCEINLINE BOOL_ InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION_* lpCriticalSection, DWORD_ dwSpinCount)
  109. {
  110. return ::InitializeCriticalSectionAndSpinCount(winapi::detail::cast_ptr(lpCriticalSection), dwSpinCount);
  111. }
  112. // CRITICAL_SECTION_NO_DEBUG_INFO is defined for WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
  113. const DWORD_ CRITICAL_SECTION_NO_DEBUG_INFO_ = 0x01000000;
  114. const DWORD_ CRITICAL_SECTION_FLAG_NO_DEBUG_INFO_ = CRITICAL_SECTION_NO_DEBUG_INFO_;
  115. const DWORD_ CRITICAL_SECTION_FLAG_DYNAMIC_SPIN_ = 0x02000000; // undocumented
  116. const DWORD_ CRITICAL_SECTION_FLAG_STATIC_INIT_ = 0x04000000; // undocumented
  117. #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
  118. BOOST_FORCEINLINE BOOL_ InitializeCriticalSectionEx(CRITICAL_SECTION_* lpCriticalSection, DWORD_ dwSpinCount, DWORD_ Flags)
  119. {
  120. return ::InitializeCriticalSectionEx(winapi::detail::cast_ptr(lpCriticalSection), dwSpinCount, Flags);
  121. }
  122. #endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
  123. BOOST_FORCEINLINE DWORD_ SetCriticalSectionSpinCount(CRITICAL_SECTION_* lpCriticalSection, DWORD_ dwSpinCount)
  124. {
  125. return ::SetCriticalSectionSpinCount(winapi::detail::cast_ptr(lpCriticalSection), dwSpinCount);
  126. }
  127. #endif // BOOST_USE_WINAPI_VERSION >= 0x0403
  128. #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_NT4
  129. BOOST_FORCEINLINE BOOL_ TryEnterCriticalSection(CRITICAL_SECTION_* lpCriticalSection)
  130. {
  131. return ::TryEnterCriticalSection(winapi::detail::cast_ptr(lpCriticalSection));
  132. }
  133. #endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_NT4
  134. BOOST_FORCEINLINE VOID_ DeleteCriticalSection(CRITICAL_SECTION_* lpCriticalSection)
  135. {
  136. ::DeleteCriticalSection(winapi::detail::cast_ptr(lpCriticalSection));
  137. }
  138. }
  139. }
  140. }
  141. #endif // BOOST_DETAIL_WINAPI_CRITICAL_SECTION_HPP