]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/thread/win32/basic_recursive_mutex.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / thread / win32 / basic_recursive_mutex.hpp
1 #ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
2 #define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
3
4 // basic_recursive_mutex.hpp
5 //
6 // (C) Copyright 2006-8 Anthony Williams
7 // (C) Copyright 2011-2012,2017-2018 Vicente J. Botet Escriba
8 //
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12
13 #include <boost/thread/win32/thread_primitives.hpp>
14 #include <boost/thread/win32/basic_timed_mutex.hpp>
15 #ifdef BOOST_THREAD_USES_CHRONO
16 #include <boost/chrono/system_clocks.hpp>
17 #include <boost/chrono/ceil.hpp>
18 #endif
19
20 #include <boost/config/abi_prefix.hpp>
21
22 namespace boost
23 {
24 namespace detail
25 {
26 template<typename underlying_mutex_type>
27 struct basic_recursive_mutex_impl
28 {
29 long recursion_count;
30 long locking_thread_id;
31 underlying_mutex_type mutex;
32
33 void initialize()
34 {
35 recursion_count=0;
36 locking_thread_id=0;
37 mutex.initialize();
38 }
39
40 void destroy()
41 {
42 mutex.destroy();
43 }
44
45 bool try_lock() BOOST_NOEXCEPT
46 {
47 long const current_thread_id=boost::winapi::GetCurrentThreadId();
48 return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);
49 }
50
51 void lock()
52 {
53 long const current_thread_id=boost::winapi::GetCurrentThreadId();
54 if(!try_recursive_lock(current_thread_id))
55 {
56 mutex.lock();
57 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
58 recursion_count=1;
59 }
60 }
61 #if defined BOOST_THREAD_USES_DATETIME
62 bool timed_lock(::boost::system_time const& target)
63 {
64 long const current_thread_id=boost::winapi::GetCurrentThreadId();
65 return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
66 }
67 template<typename Duration>
68 bool timed_lock(Duration const& target)
69 {
70 long const current_thread_id=boost::winapi::GetCurrentThreadId();
71 return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
72 }
73 #endif
74
75 #ifdef BOOST_THREAD_USES_CHRONO
76 template <class Rep, class Period>
77 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
78 {
79 long const current_thread_id=boost::winapi::GetCurrentThreadId();
80 return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time);
81 }
82 template <class Clock, class Duration>
83 bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
84 {
85 long const current_thread_id=boost::winapi::GetCurrentThreadId();
86 return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t);
87 }
88 #endif
89 void unlock()
90 {
91 if(!--recursion_count)
92 {
93 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0);
94 mutex.unlock();
95 }
96 }
97
98 private:
99 bool try_recursive_lock(long current_thread_id) BOOST_NOEXCEPT
100 {
101 if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id)
102 {
103 ++recursion_count;
104 return true;
105 }
106 return false;
107 }
108
109 bool try_basic_lock(long current_thread_id) BOOST_NOEXCEPT
110 {
111 if(mutex.try_lock())
112 {
113 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
114 recursion_count=1;
115 return true;
116 }
117 return false;
118 }
119
120 #if defined BOOST_THREAD_USES_DATETIME
121 bool try_timed_lock(long current_thread_id,::boost::system_time const& target)
122 {
123 if(mutex.timed_lock(target))
124 {
125 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
126 recursion_count=1;
127 return true;
128 }
129 return false;
130 }
131 template<typename Duration>
132 bool try_timed_lock(long current_thread_id,Duration const& target)
133 {
134 if(mutex.timed_lock(target))
135 {
136 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
137 recursion_count=1;
138 return true;
139 }
140 return false;
141 }
142 #endif
143 template <typename TP>
144 bool try_timed_lock_until(long current_thread_id,TP const& target)
145 {
146 if(mutex.try_lock_until(target))
147 {
148 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
149 recursion_count=1;
150 return true;
151 }
152 return false;
153 }
154 template <typename D>
155 bool try_timed_lock_for(long current_thread_id,D const& target)
156 {
157 if(mutex.try_lock_for(target))
158 {
159 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
160 recursion_count=1;
161 return true;
162 }
163 return false;
164 }
165 };
166
167 typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex;
168 typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_timed_mutex;
169 }
170 }
171
172 #define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0}
173
174 #include <boost/config/abi_suffix.hpp>
175
176 #endif