8 #ifndef _UTILS_SHARED_MUTEX_HPP_
9 #define _UTILS_SHARED_MUTEX_HPP_
11 #if defined(__has_include) && __has_include(<version>)
16 #if defined(__has_include) && __has_include(<version>) && !defined(__cpp_lib_shared_mutex) || \
18 ( !(defined(__has_include) && __has_include(<version>)) && \
19 !(defined(HAVE_CXX17) && HAVE_CXX17) && __cplusplus < 201703 )
22 #include <condition_variable>
24 #include <system_error>
30 typedef std::mutex mutex_t;
31 typedef std::condition_variable cond_t;
32 typedef unsigned count_t;
39 static const count_t write_entered_ = 1U << (
sizeof(count_t) * CHAR_BIT - 1);
40 static const count_t n_readers_ = ~write_entered_;
51 std::lock_guard<mutex_t> _(mut_);
63 std::unique_lock<mutex_t> lk(mut_);
64 while (state_ & write_entered_)
68 state_ |= write_entered_;
69 while (state_ & n_readers_)
77 std::unique_lock<mutex_t> lk(mut_);
80 state_ = write_entered_;
88 std::lock_guard<mutex_t> _(mut_);
97 std::unique_lock<mutex_t> lk(mut_);
98 while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
102 count_t num_readers = (state_ & n_readers_) + 1;
103 state_ &= ~n_readers_;
104 state_ |= num_readers;
109 std::unique_lock<mutex_t> lk(mut_);
110 count_t num_readers = state_ & n_readers_;
111 if (!(state_ & write_entered_) && num_readers != n_readers_)
114 state_ &= ~n_readers_;
115 state_ |= num_readers;
123 std::lock_guard<mutex_t> _(mut_);
124 count_t num_readers = (state_ & n_readers_) - 1;
125 state_ &= ~n_readers_;
126 state_ |= num_readers;
127 if (state_ & write_entered_)
129 if (num_readers == 0)
136 if (num_readers == n_readers_ - 1)
145 template <
class Mutex>
190 , owns_(m.try_lock_shared())
202 template <
class Clock,
class Duration>
205 const std::chrono::time_point<Clock, Duration>& abs_time)
207 , owns_(m.try_lock_shared_until(abs_time))
211 template <
class Rep,
class Period>
214 const std::chrono::duration<Rep, Period>& rel_time)
216 , owns_(m.try_lock_shared_for(rel_time))
238 sl.m_ =
nullptr; sl.owns_ =
false;
256 std::unique_lock<mutex_type>&& ul)
262 m_->unlock_and_lock_shared();
269 template <
class Rep,
class Period>
271 const std::chrono::duration<Rep, Period>& rel_time)
273 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
276 template <
class Clock,
class Duration>
279 const std::chrono::time_point<Clock, Duration>& abs_time);
286 std::swap(owns_, u.owns_);
302 operator int __nat::* ()
const {
303 return owns_ ? &__nat::_ : 0;
312 template <
class Mutex>
318 throw std::system_error(std::error_code(EPERM, std::system_category()),
319 "shared_lock::lock: references null mutex");
323 throw std::system_error(std::error_code(EDEADLK, std::system_category()),
324 "shared_lock::lock: already locked");
330 template <
class Mutex>
336 throw std::system_error(std::error_code(EPERM, std::system_category()),
337 "shared_lock::try_lock: references null mutex");
341 throw std::system_error(std::error_code(EDEADLK, std::system_category()),
342 "shared_lock::try_lock: already locked");
344 owns_ = m_->try_lock_shared();
352 #include <shared_mutex>
356 using shared_mutex = std::shared_mutex;
357 template<
class Mutex >
358 using shared_lock = std::shared_lock<Mutex>;
Definition: shared_mutex.hpp:147
shared_lock(mutex_type &m, const std::chrono::duration< Rep, Period > &rel_time)
Definition: shared_mutex.hpp:212
bool try_lock_until(const std::chrono::time_point< Clock, Duration > &abs_time)
shared_lock(shared_lock &&sl)
Definition: shared_mutex.hpp:233
void swap(shared_lock &&u)
Definition: shared_mutex.hpp:282
shared_lock(mutex_type &m)
Definition: shared_mutex.hpp:170
mutex_type * mutex() const
Definition: shared_mutex.hpp:305
Mutex mutex_type
Definition: shared_mutex.hpp:150
shared_lock()
Definition: shared_mutex.hpp:164
bool try_lock_for(const std::chrono::duration< Rep, Period > &rel_time)
Definition: shared_mutex.hpp:270
shared_lock(std::unique_lock< mutex_type > &&ul)
Definition: shared_mutex.hpp:255
shared_lock(mutex_type &m, std::adopt_lock_t)
Definition: shared_mutex.hpp:194
shared_lock(shared_lock const &)=delete
bool try_lock()
Definition: shared_mutex.hpp:332
void lock()
Definition: shared_mutex.hpp:314
shared_lock(mutex_type &m, std::try_to_lock_t)
Definition: shared_mutex.hpp:186
shared_lock(mutex_type &m, const std::chrono::time_point< Clock, Duration > &abs_time)
Definition: shared_mutex.hpp:203
bool owns_lock() const
Definition: shared_mutex.hpp:297
mutex_type * release()
Definition: shared_mutex.hpp:289
shared_lock(mutex_type &m, std::defer_lock_t)
Definition: shared_mutex.hpp:178
~shared_lock()
Definition: shared_mutex.hpp:220
shared_lock & operator=(shared_lock const &)=delete
Definition: shared_mutex.hpp:29
bool try_lock_shared()
Definition: shared_mutex.hpp:107
~shared_mutex()
Definition: shared_mutex.hpp:49
void unlock_shared()
Definition: shared_mutex.hpp:121
void lock_shared()
Definition: shared_mutex.hpp:95
shared_mutex & operator=(const shared_mutex &)=delete
shared_mutex()
Definition: shared_mutex.hpp:44
shared_mutex(const shared_mutex &)=delete
void unlock()
Definition: shared_mutex.hpp:86
bool try_lock()
Definition: shared_mutex.hpp:75
void lock()
Definition: shared_mutex.hpp:61
eProsima namespace.
Definition: LibrarySettingsAttributes.h:23