source: mainline/uspace/lib/cpp/include/__bits/thread/shared_mutex.hpp@ 8fd0675f

Last change on this file since 8fd0675f was b57ba05, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update headers in C++ files

  • Property mode set to 100644
File size: 7.5 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef LIBCPP_THREAD_SHARED_MUTEX
8#define LIBCPP_THREAD_SHARED_MUTEX
9
10#include <__bits/thread/threading.hpp>
11#include <chrono>
12#include <mutex>
13
14namespace std
15{
16 /**
17 * 30.4.1.4.1, class shared_timed_mutex:
18 */
19
20 class shared_timed_mutex
21 {
22 public:
23 shared_timed_mutex() noexcept;
24 ~shared_timed_mutex();
25
26 shared_timed_mutex(const shared_timed_mutex&) = delete;
27 shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
28
29 void lock();
30 bool try_lock();
31 void unlock();
32
33 template<class Rep, class Period>
34 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
35 {
36 auto time = aux::threading::time::convert(rel_time);
37
38 return aux::threading::shared_mutex::try_lock_for(time);
39 }
40
41 template<class Clock, class Duration>
42 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
43 {
44 auto dur = (abs_time - Clock::now());
45 auto time = aux::threading::time::convert(dur);
46
47 return aux::threading::shared_mutex::try_lock_for(time);
48 }
49
50 void lock_shared();
51 bool try_lock_shared();
52 void unlock_shared();
53
54 template<class Rep, class Period>
55 bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
56 {
57 auto time = aux::threading::time::convert(rel_time);
58
59 return aux::threading::shared_mutex::try_lock_shared_for(time);
60 }
61
62 template<class Clock, class Duration>
63 bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
64 {
65 auto dur = (abs_time - Clock::now());
66 auto time = aux::threading::time::convert(dur);
67
68 return aux::threading::shared_mutex::try_lock_shared_for(time);
69 }
70
71 using native_handle_type = aux::shared_mutex_t*;
72 native_handle_type native_handle();
73
74 private:
75 aux::shared_mutex_t mtx_;
76 };
77
78 /**
79 * 30.4.2.3, class template shared_lock:
80 */
81
82 template<class Mutex>
83 class shared_lock
84 {
85 public:
86 using mutex_type = Mutex;
87
88 /**
89 * 30.4.2.2.1, construction/copy/destroy:
90 */
91
92 shared_lock() noexcept
93 : mtx_{nullptr}, owns_{false}
94 { /* DUMMY BODY */ }
95
96 explicit shared_lock(mutex_type& mtx)
97 : mtx_{&mtx}, owns_{true}
98 {
99 mtx_->lock_shared();
100 }
101
102 shared_lock(mutex_type& mtx, defer_lock_t) noexcept
103 : mtx_{&mtx}, owns_{false}
104 { /* DUMMY BODY */ }
105
106 shared_lock(mutex_type& mtx, try_to_lock_t)
107 : mtx_{&mtx}, owns_{}
108 {
109 owns_ = mtx_->try_lock_shared();
110 }
111
112 shared_lock(mutex_type& mtx, adopt_lock_t)
113 : mtx_{&mtx}, owns_{true}
114 { /* DUMMY BODY */ }
115
116 template<class Clock, class Duration>
117 shared_lock(mutex_type& mtx, const chrono::time_point<Clock, Duration>& abs_time)
118 : mtx_{&mtx}, owns_{}
119 {
120 owns_ = mtx_->try_lock_shared_until(abs_time);
121 }
122
123 template<class Rep, class Period>
124 shared_lock(mutex_type& mtx, const chrono::duration<Rep, Period>& rel_time)
125 : mtx_{&mtx}, owns_{}
126 {
127 owns_ = mtx_->try_lock_shared_for(rel_time);
128 }
129
130 ~shared_lock()
131 {
132 if (owns_)
133 mtx_->unlock_shared();
134 }
135
136 shared_lock(const shared_lock&) = delete;
137 shared_lock& operator=(const shared_lock&) = delete;
138
139 shared_lock(shared_lock&& other) noexcept
140 : mtx_{move(other.mtx_)}, owns_{move(other.owns_)}
141 {
142 other.mtx_ = nullptr;
143 other.owns_ = false;
144 }
145
146 shared_lock& operator=(shared_lock&& other)
147 {
148 if (owns_)
149 mtx_->unlock_shared();
150
151 mtx_ = move(other.mtx_);
152 owns_ = move(other.owns_);
153
154 other.mtx_ = nullptr;
155 other.owns_ = false;
156 }
157
158 /**
159 * 30.4.2.2.2, locking:
160 */
161
162 void lock()
163 {
164 /**
165 * TODO:
166 * throw system_error operation_not_permitted if mtx_ == nullptr
167 * throw system_error resource_deadlock_would_occur if owns_ == true
168 */
169
170 mtx_->lock_shared();
171 owns_ = true;
172 }
173
174 bool try_lock()
175 {
176 /**
177 * TODO:
178 * throw system_error operation_not_permitted if mtx_ == nullptr
179 * throw system_error resource_deadlock_would_occur if owns_ == true
180 */
181
182 owns_ = mtx_->try_lock_shared();
183
184 return owns_;
185 }
186
187 template<class Rep, class Period>
188 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
189 {
190 /**
191 * TODO:
192 * throw system_error operation_not_permitted if mtx_ == nullptr
193 * throw system_error resource_deadlock_would_occur if owns_ == true
194 */
195
196 owns_ = mtx_->try_lock_shared_for(rel_time);
197
198 return owns_;
199 }
200
201 template<class Clock, class Duration>
202 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
203 {
204 /**
205 * TODO:
206 * throw system_error operation_not_permitted if mtx_ == nullptr
207 * throw system_error resource_deadlock_would_occur if owns_ == true
208 */
209
210 owns_ = mtx_->try_lock_shared_until(abs_time);
211
212 return owns_;
213 }
214
215 void unlock()
216 {
217 /**
218 * TODO:
219 * throw system_error operation_not_permitted if owns_ == false
220 */
221
222 mtx_->unlock_shared();
223 }
224
225 /**
226 * 30.4.2.2.3, modifiers:
227 */
228
229 void swap(shared_lock& other) noexcept
230 {
231 std::swap(mtx_, other.mtx_);
232 std::swap(owns_, other.owns_);
233 }
234
235 mutex_type* release() noexcept
236 {
237 auto ret = mtx_;
238 mtx_ = nullptr;
239 owns_ = false;
240
241 return ret;
242 }
243
244 /**
245 * 30.4.2.2.4, observers:
246 */
247
248 bool owns_lock() const noexcept
249 {
250 return owns_;
251 }
252
253 explicit operator bool() const noexcept
254 {
255 return owns_;
256 }
257
258 mutex_type* mutex() const noexcept
259 {
260 return mtx_;
261 }
262
263 private:
264 mutex_type* mtx_;
265 bool owns_;
266 };
267
268 template<class Mutex>
269 void swap(shared_lock<Mutex>& lhs, shared_lock<Mutex>& rhs) noexcept
270 {
271 lhs.swap(rhs);
272 }
273}
274
275#endif
Note: See TracBrowser for help on using the repository browser.