]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/regex/src/static_mutex.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / regex / src / static_mutex.cpp
1 /*
2 *
3 * Copyright (c) 2004
4 * John Maddock
5 *
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 *
10 */
11
12 /*
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE static_mutex.cpp
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Declares static_mutex lock type.
17 */
18
19 #define BOOST_REGEX_SOURCE
20 #include <boost/config.hpp>
21 #include <boost/assert.hpp>
22
23 #ifdef BOOST_HAS_THREADS
24
25 #include <boost/regex/pending/static_mutex.hpp>
26
27 #if defined(BOOST_HAS_WINTHREADS)
28 #ifndef NOMINMAX
29 # define NOMINMAX
30 #endif
31 #define WIN32_LEAN_AND_MEAN
32 #include <windows.h>
33 #include <boost/static_assert.hpp>
34 #endif
35
36
37 namespace boost{
38
39 #if defined(BOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)
40
41 scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex& m, bool lk)
42 : m_mutex(m), m_have_lock(false)
43 {
44 if(lk)
45 lock();
46 }
47
48 scoped_static_mutex_lock::~scoped_static_mutex_lock()
49 {
50 if(m_have_lock)
51 unlock();
52 }
53
54 void scoped_static_mutex_lock::lock()
55 {
56 if(0 == m_have_lock)
57 {
58 // Client code will throw if this fails:
59 m_have_lock = (pthread_mutex_lock(&(m_mutex.m_mutex)) == 0);
60 }
61 }
62
63 void scoped_static_mutex_lock::unlock()
64 {
65 if(m_have_lock)
66 {
67 // If this fails there's nothing we can do except assert,
68 // exceptions are out of the question as this code is called
69 // from the lock's destructor:
70 BOOST_VERIFY(pthread_mutex_unlock(&(m_mutex.m_mutex)) == 0);
71 m_have_lock = false;
72 }
73 }
74
75 #elif defined(BOOST_HAS_WINTHREADS)
76
77 BOOST_STATIC_ASSERT(sizeof(LONG) == sizeof(boost::int32_t));
78
79 scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex& m, bool lk)
80 : m_mutex(m), m_have_lock(false)
81 {
82 if(lk)
83 lock();
84 }
85
86 scoped_static_mutex_lock::~scoped_static_mutex_lock()
87 {
88 if(m_have_lock)
89 unlock();
90 }
91
92 void scoped_static_mutex_lock::lock()
93 {
94 if(0 == m_have_lock)
95 {
96 #if !defined(InterlockedCompareExchangePointer)
97 while(0 != InterlockedCompareExchange(reinterpret_cast<void**>((boost::uint_least16_t*)&(m_mutex.m_mutex)), (void*)1, 0))
98 #else
99 while(0 != InterlockedCompareExchange(reinterpret_cast<LONG*>(&(m_mutex.m_mutex)), 1, 0))
100 #endif
101 {
102 Sleep(0);
103 }
104 m_have_lock = true;
105 }
106 }
107
108 void scoped_static_mutex_lock::unlock()
109 {
110 if(m_have_lock)
111 {
112 #if !defined(InterlockedCompareExchangePointer)
113 InterlockedExchange((LONG*)&(m_mutex.m_mutex), 0);
114 #else
115 InterlockedExchange(reinterpret_cast<LONG*>(&(m_mutex.m_mutex)), 0);
116 #endif
117 m_have_lock = false;
118 }
119 }
120
121 #else
122 //
123 // Portable version of a static mutex based on Boost.Thread library:
124 //
125 #include <stdlib.h>
126 #include <boost/assert.hpp>
127
128 boost::recursive_mutex* static_mutex::m_pmutex = 0;
129 boost::once_flag static_mutex::m_once = BOOST_ONCE_INIT;
130
131 extern "C" BOOST_REGEX_DECL void boost_regex_free_static_mutex()
132 {
133 delete static_mutex::m_pmutex;
134 static_mutex::m_pmutex = 0;
135 }
136
137 void static_mutex::init()
138 {
139 m_pmutex = new boost::recursive_mutex();
140 int r = atexit(boost_regex_free_static_mutex);
141 BOOST_ASSERT(0 == r);
142 }
143
144 scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex& , bool lk)
145 : m_plock(0), m_have_lock(false)
146 {
147 if(lk)
148 lock();
149 }
150
151 scoped_static_mutex_lock::~scoped_static_mutex_lock()
152 {
153 if(m_have_lock)
154 unlock();
155 delete m_plock;
156 }
157
158 void scoped_static_mutex_lock::lock()
159 {
160 if(0 == m_have_lock)
161 {
162 boost::call_once(static_mutex::m_once,&static_mutex::init);
163 if(0 == m_plock)
164 m_plock = new boost::unique_lock<boost::recursive_mutex>(*static_mutex::m_pmutex, boost::defer_lock);
165 m_plock->lock();
166 m_have_lock = true;
167 }
168 }
169
170 void scoped_static_mutex_lock::unlock()
171 {
172 if(m_have_lock)
173 {
174 m_plock->unlock();
175 m_have_lock = false;
176 }
177 }
178
179 #endif
180
181 }
182
183 #endif // BOOST_HAS_THREADS