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 24 #ifndef BOOST_CONFIG_HPP 25 # include <boost/config.hpp> 26 #endif 27 # 28 #if defined(BOOST_HAS_PRAGMA_ONCE) 29 # pragma once 30 #endif 31 32 #ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP 33 #define BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP 34 35 #include <boost/container/detail/config_begin.hpp> 36 #include <boost/container/detail/workaround.hpp> 37 38 #if defined(BOOST_HAS_PTHREADS) 39 40 #include <pthread.h> 41 #include <boost/assert.hpp> 42 43 namespace boost{ 44 namespace container { 45 namespace dtl { 46 47 class thread_mutex 48 { 49 public: thread_mutex()50 thread_mutex() 51 { 52 BOOST_VERIFY(pthread_mutex_init(&m_mut, 0) == 0); 53 } 54 ~thread_mutex()55 ~thread_mutex() 56 { 57 BOOST_VERIFY(pthread_mutex_destroy(&m_mut) == 0); 58 } 59 lock()60 void lock() 61 { 62 BOOST_VERIFY(pthread_mutex_lock( &m_mut) == 0); 63 } 64 unlock()65 void unlock() 66 { 67 BOOST_VERIFY(pthread_mutex_unlock(&m_mut) == 0); 68 } 69 70 private: 71 thread_mutex(thread_mutex const &); 72 thread_mutex & operator=(thread_mutex const &); 73 74 pthread_mutex_t m_mut; 75 }; 76 77 } // namespace dtl { 78 } // namespace container { 79 } // namespace boost { 80 81 #else //!BOOST_HAS_PTHREADS (Windows implementation) 82 83 #ifdef BOOST_USE_WINDOWS_H 84 85 #include <windows.h> 86 87 namespace boost{ 88 namespace container { 89 namespace dtl { 90 91 typedef ::CRITICAL_SECTION win_critical_section; 92 93 } // namespace dtl { 94 } // namespace container { 95 } // namespace boost { 96 97 #else //! BOOST_USE_WINDOWS_H 98 99 struct _RTL_CRITICAL_SECTION_DEBUG; 100 struct _RTL_CRITICAL_SECTION; 101 102 namespace boost{ 103 namespace container { 104 namespace dtl { 105 106 #ifdef BOOST_PLAT_WINDOWS_UWP 107 extern "C" __declspec(dllimport) int __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long); 108 #else 109 extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *); 110 #endif 111 extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *); 112 extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *); 113 extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *); 114 115 struct win_critical_section 116 { 117 struct _RTL_CRITICAL_SECTION_DEBUG * DebugInfo; 118 long LockCount; 119 long RecursionCount; 120 void * OwningThread; 121 void * LockSemaphore; 122 #if defined(_WIN64) 123 unsigned __int64 SpinCount; 124 #else 125 unsigned long SpinCount; 126 #endif 127 }; 128 129 } // namespace dtl { 130 } // namespace container { 131 } // namespace boost { 132 133 #endif //BOOST_USE_WINDOWS_H 134 135 namespace boost{ 136 namespace container { 137 namespace dtl { 138 139 class thread_mutex 140 { 141 public: thread_mutex()142 thread_mutex() 143 { 144 #ifdef BOOST_PLAT_WINDOWS_UWP 145 (InitializeCriticalSectionEx)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect), 4000, 0); 146 #else 147 (InitializeCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); 148 #endif 149 } 150 lock()151 void lock() 152 { 153 (EnterCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); 154 } 155 unlock()156 void unlock() 157 { 158 (LeaveCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); 159 } 160 ~thread_mutex()161 ~thread_mutex() 162 { 163 (DeleteCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); 164 } 165 166 private: 167 thread_mutex(thread_mutex const &); 168 thread_mutex & operator=(thread_mutex const &); 169 170 win_critical_section m_crit_sect; 171 }; 172 173 } // namespace dtl { 174 } // namespace container { 175 } // namespace boost { 176 177 #endif //BOOST_HAS_PTHREADS 178 179 #include <boost/container/detail/config_end.hpp> 180 181 #endif // #ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP 182