fairness  v1.0.0
A collection of advanced syncronization mechanisms.
Loading...
Searching...
No Matches
shared_lock.hpp
Go to the documentation of this file.
1
14#ifndef BOOST_FAIRNESS_SHARED_LOCK_HPP
15#define BOOST_FAIRNESS_SHARED_LOCK_HPP
18#include <stdexcept>
19#include <system_error>
20#include <memory>
21#include <chrono>
22
23// maybe also all the constructors should check for the validity of the priority
24
25namespace boost::fairness{
26
37 template<typename Lockable>
39
40 public:
41
46 shared_lock() noexcept : lockable_(nullptr), lockOwned_(false), currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY)
47 { }
48
56 explicit shared_lock(Lockable& m, Priority_t const p = BOOST_FAIRNESS_MINIMUM_PRIORITY)
57 : lockable_(std::addressof(m)), lockOwned_(false), currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
58 if (!is_valid_priority(p))
59 throw_operation_not_permitted_();
60 m.lock_shared();
61 lockOwned_ = true;
62 currentPriority_ = p;
63 }
64
71 shared_lock(Lockable& m, defer_lock_t) noexcept
72 : lockable_(std::addressof(m)), lockOwned_(false), currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY)
73 { }
74
81 shared_lock(Lockable& m, try_to_lock_t)
82 : lockable_(std::addressof(m)), lockOwned_(m.try_lock_shared(BOOST_FAIRNESS_MINIMUM_PRIORITY)), currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
83 if (lockOwned_)
84 currentPriority_ = BOOST_FAIRNESS_MINIMUM_PRIORITY;
85 }
86
94 shared_lock(Lockable& m, Priority_t const p, try_to_lock_t)
95 : lockable_(std::addressof(m)), lockOwned_(lockable_->try_lock_shared(p)), currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
96 if (lockOwned_)
97 currentPriority_ = p;
98 }
99
107 shared_lock(Lockable& m, Priority_t const p, adopt_lock_t) noexcept
108 : lockable_(std::addressof(m)), lockOwned_(true), currentPriority_(p)
109 { }
110
121 template<typename Clock, typename Duration>
122 shared_lock(Lockable& m, const std::chrono::time_point<Clock, Duration>& atime, Priority_t p = BOOST_FAIRNESS_MINIMUM_PRIORITY)
123 : lockable_(std::addressof(m)),
124 lockOwned_(lockable_->try_lock_shared_until(atime, p)),
125 currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
126 if (lockOwned_)
127 currentPriority_ = p;
128 }
129
140 template<typename Rep, typename Period>
141 shared_lock(Lockable& m, const std::chrono::duration<Rep, Period>& rtime, Priority_t p = BOOST_FAIRNESS_MINIMUM_PRIORITY)
142 : lockable_(std::addressof(m)),
143 lockOwned_(lockable_->try_lock_shared_for(rtime, p)),
144 currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
145 if (lockOwned_)
146 currentPriority_ = p;
147 }
148
153 ~shared_lock(){
154 if (lockOwned_)
155 lockable_->unlock_shared();
156 }
157
162 shared_lock(const shared_lock&) = delete;
163
170 shared_lock& operator=(const shared_lock&) = delete;
171
178 shared_lock(shared_lock&& other) noexcept
179 : lockable_(other.lockable_), lockOwned_(other.lockOwned_), currentPriority_(other.currentPriority_){
180 other.lockable_ = 0;
181 other.lockOwned_ = false;
182 other.currentPriority_ = BOOST_FAIRNESS_INVALID_PRIORITY;
183 }
184
192 shared_lock& operator=(shared_lock&& other) noexcept{
193 if(lockOwned_)
194 unlock();
195 shared_lock(std::move(other)).swap(*this);
196 other.lockable_ = 0;
197 other.lockOwned_ = false;
198 other.currentPriority_ = BOOST_FAIRNESS_INVALID_PRIORITY;
199 return *this;
200 }
201
207 void swap(shared_lock& other) noexcept{
208 std::swap(lockable_, other.lockable_);
209 std::swap(lockOwned_, other.lockOwned_);
210 std::swap(currentPriority_, other.currentPriority_);
211 }
212
220 Lockable* release() noexcept{
221 Lockable* __ret = lockable_;
222 lockable_ = 0;
223 lockOwned_ = false;
224 currentPriority_ = BOOST_FAIRNESS_INVALID_PRIORITY;
225 return __ret;
226 }
227
235 bool owns_lock() const noexcept
236 { return lockOwned_; }
237
243 Priority_t lock_priority()const noexcept
244 { return currentPriority_; }
245
253 explicit operator bool() const noexcept
254 { return owns_lock(); }
255
262 explicit operator Priority_t() const noexcept
263 { return lock_priority(); }
264
270 Lockable* mutex() const noexcept
271 { return lockable_; }
272
287 if (!lockable_ || !is_valid_priority(p))
288 throw_operation_not_permitted_();
289 else if (lockOwned_)
290 throw_resource_deadlock_would_occur_();
291 else
292 {
293 lockable_->lock_shared(p);
294 lockOwned_ = true;
295 currentPriority_ = p;
296 }
297 }
298
309 if (!lockable_ || !is_valid_priority(p))
310 throw_operation_not_permitted_();
311 else if (lockOwned_)
312 throw_resource_deadlock_would_occur_();
313 else
314 {
315 lockOwned_ = lockable_->try_lock_shared(p);
316 if (lockOwned_)
317 currentPriority_ = p;
318 return lockOwned_;
319 }
320 }
321
334 void unlock(){
335 if (!lockOwned_)
336 throw_operation_not_permitted_();
337 else if (lockable_)
338 {
339 lockable_->unlock_shared();
340 currentPriority_ = BOOST_FAIRNESS_INVALID_PRIORITY;
341 lockOwned_ = false;
342 }
343 }
366 template<typename Clock, typename Duration>
367 bool try_lock_until(const std::chrono::time_point<Clock, Duration>& atime, Priority_t const p = BOOST_FAIRNESS_MINIMUM_PRIORITY){
368 if (!lockable_ || !is_valid_priority(p))
369 throw_operation_not_permitted_();
370 else if (lockOwned_)
371 throw_resource_deadlock_would_occur_();
372 else
373 {
374 lockOwned_ = lockable_->try_lock_shared_until(atime, p);
375 if (lockOwned_)
376 currentPriority_ = p;
377 return lockOwned_;
378 }
379 }
380
405 template<typename Rep, typename Period>
406 bool try_lock_for(const std::chrono::duration<Rep, Period>& rtime, Priority_t const p = BOOST_FAIRNESS_MINIMUM_PRIORITY){
407 if (!lockable_ || !is_valid_priority(p))
408 throw_operation_not_permitted_();
409 else if (lockOwned_)
410 throw_resource_deadlock_would_occur_();
411 else
412 {
413 lockOwned_ = lockable_->try_lock_shared_for(rtime, p);
414 if (lockOwned_)
415 currentPriority_ = p;
416 return lockOwned_;
417 }
418 }
419
420 private:
421
426 static inline void throw_operation_not_permitted_(){
427 throw std::system_error(std::make_error_code(std::errc::operation_not_permitted));
428 }
429
434 static inline void throw_resource_deadlock_would_occur_(){
435 throw std::system_error(std::make_error_code(std::errc::resource_deadlock_would_occur));
436 }
437
438 Priority_t currentPriority_;
439 Lockable* lockable_;
440 bool lockOwned_;
441
442 };
443
444 template<typename Lockable>
445 inline void swap(shared_lock<Lockable>& lhs, shared_lock<Lockable>& rhs) noexcept
446 { lhs.swap(rhs); }
447
448}
449
450#endif // BOOST_FAIRNESS_SHARED_LOCK_HPP
Empty types used by unique_lock and shared_lock constructors.
The class shared_lock is a general-purpose shared mutex ownership wrapper allowing deferred locking,...
Definition shared_lock.hpp:38
Lockable * mutex() const noexcept
Returns a pointer to the associated mutex, or a null pointer if there is no associated mutex.
Definition shared_lock.hpp:270
Lockable * release() noexcept
Breaks the association of the associated mutex, if any, and *this. No locks are unlocked....
Definition shared_lock.hpp:220
void unlock()
Unlocks the associated mutex from shared mode. Effectively calls mutex()->unlock_shared()....
Definition shared_lock.hpp:334
bool try_lock(Priority_t const p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Tries to lock the associated mutex in shared mode without blocking. Effectively calls mutex()->try_lo...
Definition shared_lock.hpp:308
bool owns_lock() const noexcept
Checks whether *this owns a locked mutex or not.
Definition shared_lock.hpp:235
bool try_lock_for(const std::chrono::duration< Rep, Period > &rtime, Priority_t const p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Tries to lock the associated mutex in shared mode. Blocks until specified rtime has elapsed or the lo...
Definition shared_lock.hpp:406
void swap(shared_lock &other) noexcept
Exchanges the internal states of the lock objects.
Definition shared_lock.hpp:207
void lock(Priority_t const p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Locks the associated mutex in shared mode. Effectively calls mutex()->lock_shared().
Definition shared_lock.hpp:286
Priority_t lock_priority() const noexcept
Checks the current priority of *this. #TODO.
Definition shared_lock.hpp:243
bool try_lock_until(const std::chrono::time_point< Clock, Duration > &atime, Priority_t const p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Tries to lock the associated mutex in shared mode. Blocks until specified atime has been reached or t...
Definition shared_lock.hpp:367
Definition acquisition_modes.hpp:16
uint8_t Priority_t
Definition priority_t.hpp:17
bool is_valid_priority(Priority_t const p)
allows you to verify that an input priority is valid. Has to be in the range [BOOST_FAIRNESS_MINIMUM_...
Definition priority_t.hpp:45
void swap(shared_lock< Lockable > &lhs, shared_lock< Lockable > &rhs) noexcept
Definition shared_lock.hpp:445
Alias the type Priority_t. Priority_t is the type of priorities that are used by the priority_mutexes...
#define BOOST_FAIRNESS_MINIMUM_PRIORITY
Priorities are indexes in an array, that means that if I define a priority_mutex<BOOST_FAIRNESS_MAXIM...
Definition priority_t.hpp:36
#define BOOST_FAIRNESS_INVALID_PRIORITY
A number indicating an invalid priority which is not usable by the mutexes.
Definition priority_t.hpp:29