thread_mutex.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2018-2018. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/interprocess for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. //////////////////////////////////////////////////////////////////////////////
  11. //
  12. // This code is partially based on the lightweight mutex implemented
  13. // by Boost.SmartPtr:
  14. //
  15. // Copyright (c) 2002, 2003 Peter Dimov
  16. // Copyright (c) Microsoft Corporation 2014
  17. //
  18. // Distributed under the Boost Software License, Version 1.0. (See
  19. // accompanying file LICENSE_1_0.txt or copy at
  20. // http://www.boost.org/LICENSE_1_0.txt)
  21. //
  22. //////////////////////////////////////////////////////////////////////////////
  23. #ifndef BOOST_CONFIG_HPP
  24. # include <boost/config.hpp>
  25. #endif
  26. #
  27. #if defined(BOOST_HAS_PRAGMA_ONCE)
  28. # pragma once
  29. #endif
  30. #ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP
  31. #define BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP
  32. #include <boost/container/detail/config_begin.hpp>
  33. #include <boost/container/detail/workaround.hpp>
  34. #if defined(BOOST_HAS_PTHREADS)
  35. #include <pthread.h>
  36. #include <boost/assert.hpp>
  37. namespace boost{
  38. namespace container {
  39. namespace dtl {
  40. class thread_mutex
  41. {
  42. public:
  43. thread_mutex()
  44. {
  45. BOOST_VERIFY(pthread_mutex_init(&m_mut, 0) == 0);
  46. }
  47. ~thread_mutex()
  48. {
  49. BOOST_VERIFY(pthread_mutex_destroy(&m_mut) == 0);
  50. }
  51. void lock()
  52. {
  53. BOOST_VERIFY(pthread_mutex_lock( &m_mut) == 0);
  54. }
  55. void unlock()
  56. {
  57. BOOST_VERIFY(pthread_mutex_unlock(&m_mut) == 0);
  58. }
  59. private:
  60. thread_mutex(thread_mutex const &);
  61. thread_mutex & operator=(thread_mutex const &);
  62. pthread_mutex_t m_mut;
  63. };
  64. } // namespace dtl {
  65. } // namespace container {
  66. } // namespace boost {
  67. #else //!BOOST_HAS_PTHREADS (Windows implementation)
  68. #ifdef BOOST_USE_WINDOWS_H
  69. #include <windows.h>
  70. namespace boost{
  71. namespace container {
  72. namespace dtl {
  73. typedef ::CRITICAL_SECTION win_critical_section;
  74. } // namespace dtl {
  75. } // namespace container {
  76. } // namespace boost {
  77. #else //! BOOST_USE_WINDOWS_H
  78. struct _RTL_CRITICAL_SECTION_DEBUG;
  79. struct _RTL_CRITICAL_SECTION;
  80. namespace boost{
  81. namespace container {
  82. namespace dtl {
  83. #ifdef BOOST_PLAT_WINDOWS_UWP
  84. extern "C" __declspec(dllimport) int __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long);
  85. #else
  86. extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *);
  87. #endif
  88. extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *);
  89. extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *);
  90. extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *);
  91. struct win_critical_section
  92. {
  93. struct _RTL_CRITICAL_SECTION_DEBUG * DebugInfo;
  94. long LockCount;
  95. long RecursionCount;
  96. void * OwningThread;
  97. void * LockSemaphore;
  98. #if defined(_WIN64)
  99. unsigned __int64 SpinCount;
  100. #else
  101. unsigned long SpinCount;
  102. #endif
  103. };
  104. } // namespace dtl {
  105. } // namespace container {
  106. } // namespace boost {
  107. #endif //BOOST_USE_WINDOWS_H
  108. namespace boost{
  109. namespace container {
  110. namespace dtl {
  111. class thread_mutex
  112. {
  113. public:
  114. thread_mutex()
  115. {
  116. #ifdef BOOST_PLAT_WINDOWS_UWP
  117. (InitializeCriticalSectionEx)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect), 4000, 0);
  118. #else
  119. (InitializeCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
  120. #endif
  121. }
  122. void lock()
  123. {
  124. (EnterCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
  125. }
  126. void unlock()
  127. {
  128. (LeaveCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
  129. }
  130. ~thread_mutex()
  131. {
  132. (DeleteCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect));
  133. }
  134. private:
  135. thread_mutex(thread_mutex const &);
  136. thread_mutex & operator=(thread_mutex const &);
  137. win_critical_section m_crit_sect;
  138. };
  139. } // namespace dtl {
  140. } // namespace container {
  141. } // namespace boost {
  142. #endif //BOOST_HAS_PTHREADS
  143. #include <boost/container/detail/config_end.hpp>
  144. #endif // #ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP