fairness  v1.0.0
A collection of advanced syncronization mechanisms.
Loading...
Searching...
No Matches
unique_lock.hpp
Go to the documentation of this file.
1
13#ifndef BOOST_FAIRNESS_UNIQUE_LOCK_HPP
14#define BOOST_FAIRNESS_UNIQUE_LOCK_HPP
16#include <stdexcept>
17#include <system_error>
18#include <memory>
19#include <chrono>
20
21// maybe also all the constructors should check for the validity of the priority
22
23namespace boost::fairness
24{
34 template <typename Lockable>
36
37 public:
42 unique_lock() noexcept
43 : lockable_(0), lockOwned_(false), currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY)
44 { }
45
53 : lockable_(std::addressof(m)), lockOwned_(false), currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
54 if (!is_valid_priority(p))
55 throw_operation_not_permitted_();
56 lock(p);
57 lockOwned_ = true;
58 currentPriority_ = p;
59 }
60
66 unique_lock(Lockable &m, defer_lock_t) noexcept
67 : lockable_(std::addressof(m)), lockOwned_(false), currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
68 }
69
76 unique_lock(Lockable &m, Priority_t const p, try_to_lock_t)
77 : lockable_(std::addressof(m)), lockOwned_(lockable_->try_lock(p)), currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
78 if (lockOwned_)
79 currentPriority_ = p;
80 }
81
87 unique_lock(Lockable &m, try_to_lock_t)
88 : lockable_(std::addressof(m)), lockOwned_(lockable_->try_lock(BOOST_FAIRNESS_MINIMUM_PRIORITY)), currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
89 if (lockOwned_)
90 currentPriority_ = BOOST_FAIRNESS_MINIMUM_PRIORITY;
91 }
92
99 unique_lock(Lockable &m, Priority_t const p, adopt_lock_t) noexcept
100 : lockable_(std::addressof(m)), lockOwned_(true), currentPriority_(p)
101 { }
102
103 /*
104 There isn`t a non intrusive way to automatically find out the priority
105 - change visibility of current priority, from private to friend
106 - currentPriority_ isn't in every mutex.
107 */
108 /*
109 unique_lock(Lockable& m, adopt_lock_t) noexcept
110 : lockable_(std::addressof(m)), lockOwned_(true), currentPriority_(m.)
111 {
112 }*/
113
123 template <typename Clock, typename Duration>
124 unique_lock(Lockable &m, const std::chrono::time_point<Clock, Duration> &atime, Priority_t p = BOOST_FAIRNESS_MINIMUM_PRIORITY)
125 : lockable_(std::addressof(m)),
126 lockOwned_(lockable_->try_lock_until(atime, p)),
127 currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
128 if (lockOwned_)
129 currentPriority_ = p;
130 }
131
141 template <typename Rep, typename Period>
142 unique_lock(Lockable &m, const std::chrono::duration<Rep, Period> &rtime, Priority_t p = BOOST_FAIRNESS_MINIMUM_PRIORITY)
143 : lockable_(std::addressof(m)),
144 lockOwned_(lockable_->try_lock_for(rtime, p)),
145 currentPriority_(BOOST_FAIRNESS_INVALID_PRIORITY){
146 if (lockOwned_)
147 currentPriority_ = p;
148 }
149
155 if (lockOwned_)
156 unlock();
157 }
158 unique_lock(const unique_lock &) = delete;
160
166 unique_lock(unique_lock &&other) noexcept
167 : lockable_(other.lockable_), lockOwned_(other.lockOwned_), currentPriority_(other.currentPriority_){
168 other.lockable_ = 0;
169 other.lockOwned_ = false;
170 other.currentPriority_ = BOOST_FAIRNESS_INVALID_PRIORITY;
171 }
172
187 if (!lockable_ || !is_valid_priority(p))
188 throw_operation_not_permitted_();
189 else if (lockOwned_)
190 throw_resource_deadlock_would_occur_();
191 else
192 {
193 lockable_->lock(p);
194 lockOwned_ = true;
195 currentPriority_ = p;
196 }
197 }
198
216 if (!lockable_ || !is_valid_priority(p))
217 throw_operation_not_permitted_();
218 else if (lockOwned_)
219 throw_resource_deadlock_would_occur_();
220 else
221 {
222 lockOwned_ = lockable_->try_lock(p);
223 if (lockOwned_)
224 currentPriority_ = p;
225 return lockOwned_;
226 }
227 }
228
242 void unlock(){
243 if (!lockOwned_)
244 throw_operation_not_permitted_();
245 else if (lockable_)
246 {
247 lockable_->unlock();
248 currentPriority_ = BOOST_FAIRNESS_INVALID_PRIORITY;
249 lockOwned_ = false;
250 }
251 }
252
275 template <typename Clock, typename Duration>
276 bool try_lock_until(const std::chrono::time_point<Clock, Duration> &atime, Priority_t const p = BOOST_FAIRNESS_MINIMUM_PRIORITY){
277 if (!lockable_ || !is_valid_priority(p))
278 throw_operation_not_permitted_();
279 else if (lockOwned_)
280 throw_resource_deadlock_would_occur_();
281 else
282 {
283 lockOwned_ = lockable_->try_lock_until(atime, p);
284 if (lockOwned_)
285 currentPriority_ = p;
286 return lockOwned_;
287 }
288 }
289
312 template <typename Rep, typename Period>
313 bool try_lock_for(const std::chrono::duration<Rep, Period> &rtime, Priority_t const p = BOOST_FAIRNESS_MINIMUM_PRIORITY){
314 if (!lockable_ || !is_valid_priority(p))
315 throw_operation_not_permitted_();
316 else if (lockOwned_)
317 throw_resource_deadlock_would_occur_();
318 else
319 {
320 lockOwned_ = lockable_->try_lock_for(rtime);
321 if (lockOwned_)
322 currentPriority_ = p;
323 return lockOwned_;
324 }
325 }
326
334 if (lockOwned_)
335 unlock();
336 unique_lock(std::move(other)).swap(*this);
337 other.lockable_ = 0;
338 other.lockOwned_ = false;
339 other.currentPriority_ = BOOST_FAIRNESS_INVALID_PRIORITY;
340 return *this;
341 }
342
349 void swap(unique_lock &other) noexcept{
350 std::swap(lockable_, other.lockable_);
351 std::swap(lockOwned_, other.lockOwned_);
352 std::swap(currentPriority_, other.currentPriority_);
353 }
354
363 Lockable *release() noexcept{
364 Lockable *__ret = lockable_;
365 lockable_ = 0;
366 lockOwned_ = false;
367 currentPriority_ = BOOST_FAIRNESS_INVALID_PRIORITY;
368 return __ret;
369 }
370
377 bool owns_lock() const noexcept
378 { return lockOwned_; }
379
385 Priority_t lock_priority() const noexcept
386 { return currentPriority_; }
387
394 explicit operator bool() const noexcept
395 { return owns_lock(); }
396
402 explicit operator Priority_t() const noexcept
403 { return lock_priority(); }
404
410 Lockable *mutex() const noexcept
411 { return lockable_; }
412
413 private:
418 static inline void throw_operation_not_permitted_()
419 { throw std::system_error(std::make_error_code(std::errc::operation_not_permitted)); }
420
425 static inline void throw_resource_deadlock_would_occur_()
426 { throw std::system_error(std::make_error_code(std::errc::resource_deadlock_would_occur)); }
427
428 Priority_t currentPriority_;
429 Lockable *lockable_;
430 bool lockOwned_;
431 };
432
440 template <typename Lockable>
441 inline void swap(unique_lock<Lockable> &lhs, unique_lock<Lockable> &rhs) noexcept
442 { lhs.swap(rhs); }
443
444}
445
446#endif // BOOST_FAIRNESS_UNIQUE_LOCK_HPP
The class unique_lock is a general-purpose mutex ownership wrapper allowing deferred locking,...
Definition unique_lock.hpp:35
unique_lock(const unique_lock &)=delete
unique_lock & operator=(unique_lock &&other) noexcept
Definition unique_lock.hpp:333
unique_lock(Lockable &m, const std::chrono::duration< Rep, Period > &rtime, Priority_t p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Construct a new unique lock object.
Definition unique_lock.hpp:142
void unlock()
Unlocks (i.e., releases ownership of) the associated mutex and releases ownership....
Definition unique_lock.hpp:242
bool try_lock(Priority_t const p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Tries to lock (i.e., takes ownership of) the associated mutex without blocking. Effectively calls mut...
Definition unique_lock.hpp:215
unique_lock & operator=(const unique_lock &)=delete
Lockable * mutex() const noexcept
Definition unique_lock.hpp:410
bool try_lock_for(const std::chrono::duration< Rep, Period > &rtime, Priority_t const p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Tries to lock (i.e., takes ownership of) the associated mutex. Blocks until specified rtime has elaps...
Definition unique_lock.hpp:313
void lock(Priority_t const p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Locks the associated mutex. Effectively calls mutex()->lock().
Definition unique_lock.hpp:186
bool owns_lock() const noexcept
Checks whether *this owns a locked mutex or not.
Definition unique_lock.hpp:377
unique_lock(unique_lock &&other) noexcept
Construct a new unique lock object.
Definition unique_lock.hpp:166
unique_lock(Lockable &m, Priority_t const p, adopt_lock_t) noexcept
Construct a new unique lock object.
Definition unique_lock.hpp:99
unique_lock(Lockable &m, const std::chrono::time_point< Clock, Duration > &atime, Priority_t p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Construct a new unique lock object.
Definition unique_lock.hpp:124
unique_lock(Lockable &m, try_to_lock_t)
Construct a new unique lock object.
Definition unique_lock.hpp:87
void swap(unique_lock &other) noexcept
Exchanges the internal states of the lock objects.
Definition unique_lock.hpp:349
Priority_t lock_priority() const noexcept
TODO.
Definition unique_lock.hpp:385
unique_lock(Lockable &m, defer_lock_t) noexcept
Construct a new unique lock object.
Definition unique_lock.hpp:66
unique_lock(Lockable &m, Priority_t const p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Construct a new unique lock object.
Definition unique_lock.hpp:52
unique_lock() noexcept
Construct a new unique lock object.
Definition unique_lock.hpp:42
bool try_lock_until(const std::chrono::time_point< Clock, Duration > &atime, Priority_t const p=BOOST_FAIRNESS_MINIMUM_PRIORITY)
Tries to lock (i.e., takes ownership of) the associated mutex. Blocks until specified atime has been ...
Definition unique_lock.hpp:276
unique_lock(Lockable &m, Priority_t const p, try_to_lock_t)
Construct a new unique lock object.
Definition unique_lock.hpp:76
~unique_lock()
Destroy the unique lock object.
Definition unique_lock.hpp:154
Lockable * release() noexcept
Breaks the association of the associated mutex, if any, and *this. No locks are unlocked....
Definition unique_lock.hpp:363
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