32#ifndef _UTILS_SHARED_MUTEX_HPP_
33#define _UTILS_SHARED_MUTEX_HPP_
36#include <condition_variable>
39#include <system_error>
57 typedef std::condition_variable
cond_t;
76 std::lock_guard<mutex_t> _(
mut_);
88 std::lock_guard<mutex_t> _(
mut_);
99 std::lock_guard<mutex_t> _(
mut_);
108 std::unique_lock<mutex_t> lk(
mut_);
120 std::lock_guard<mutex_t> _(
mut_);
134template<shared_mutex_type>
149 std::unique_lock<mutex_t> lk(mut_);
150 while (state_ & write_entered_)
154 state_ |= write_entered_;
155 while (state_ & n_readers_)
163 std::lock_guard<mutex_t> _(mut_);
164 count_t num_readers = (state_ & n_readers_) - 1;
165 state_ &= ~n_readers_;
166 state_ |= num_readers;
167 if (state_ & write_entered_)
169 if (num_readers == 0)
174 else if (num_readers == n_readers_ - 1)
194 std::unique_lock<mutex_t> lk(mut_);
196 while (state_ & n_readers_ || state_ & write_entered_)
200 state_ |= write_entered_;
206 std::lock_guard<mutex_t> _(mut_);
207 count_t num_readers = (state_ & n_readers_) - 1;
208 state_ &= ~n_readers_;
209 state_ |= num_readers;
211 if ((writer_waiting_ && num_readers == 0)
212 || (num_readers == n_readers_ - 1))
226 std::thread::id exclusive_owner_ = {};
228 std::map<std::thread::id, unsigned int> shared_owners_;
234 std::lock_guard<std::mutex> _(wm_);
242 std::lock_guard<std::mutex> _(wm_);
243 exclusive_owner_ = std::this_thread::get_id();
248 bool res = sm::try_lock();
249 std::lock_guard<std::mutex> _(wm_);
252 exclusive_owner_ = std::this_thread::get_id();
260 std::lock_guard<std::mutex> _(wm_);
261 exclusive_owner_ = std::thread::id();
269 std::lock_guard<std::mutex> _(wm_);
270 ++shared_owners_[std::this_thread::get_id()];
275 bool res = sm::try_lock_shared();
276 std::lock_guard<std::mutex> _(wm_);
279 ++shared_owners_[std::this_thread::get_id()];
287 std::lock_guard<std::mutex> _(wm_);
288 auto owner = shared_owners_.find(std::this_thread::get_id());
289 if ( owner != shared_owners_.end() && 0 == --owner->second )
291 shared_owners_.erase(owner);
300#if defined(__has_include) && __has_include(<version>)
305#if defined(__has_include) && __has_include(<version>) && !defined(__cpp_lib_shared_mutex) || \
307 ( !(defined(__has_include) && __has_include(<version>)) && \
308 !(defined(HAVE_CXX17) && HAVE_CXX17) && __cplusplus < 201703 )
312template <
class Mutex>
357 , owns_(m.try_lock_shared())
369 template <
class Clock,
class Duration>
372 const std::chrono::time_point<Clock, Duration>& abs_time)
374 , owns_(m.try_lock_shared_until(abs_time))
378 template <
class Rep,
class Period>
381 const std::chrono::duration<Rep, Period>& rel_time)
383 , owns_(m.try_lock_shared_for(rel_time))
405 sl.m_ =
nullptr; sl.owns_ =
false;
423 std::unique_lock<mutex_type>&& ul)
429 m_->unlock_and_lock_shared();
436 template <
class Rep,
class Period>
438 const std::chrono::duration<Rep, Period>& rel_time)
440 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
443 template <
class Clock,
class Duration>
446 const std::chrono::time_point<Clock, Duration>& abs_time);
453 std::swap(owns_, u.owns_);
469 operator int __nat::* ()
const {
470 return owns_ ? &__nat::_ : 0;
479template <
class Mutex>
485 throw std::system_error(std::error_code(EPERM, std::system_category()),
486 "shared_lock::lock: references null mutex");
490 throw std::system_error(std::error_code(EDEADLK, std::system_category()),
491 "shared_lock::lock: already locked");
497template <
class Mutex>
503 throw std::system_error(std::error_code(EPERM, std::system_category()),
504 "shared_lock::try_lock: references null mutex");
508 throw std::system_error(std::error_code(EDEADLK, std::system_category()),
509 "shared_lock::try_lock: already locked");
511 owns_ = m_->try_lock_shared();
515template <
class Mutex>
516template <
class Clock,
class Duration>
519 const std::chrono::time_point<Clock, Duration>& abs_time)
523 throw std::system_error(std::error_code(EPERM, std::system_category()),
524 "shared_lock::try_lock_until: references null mutex");
528 throw std::system_error(std::error_code(EDEADLK, std::system_category()),
529 "shared_lock::try_lock_until: already locked");
531 owns_ = m_->try_lock_shared_until(abs_time);
535template <
class Mutex>
541 throw std::system_error(std::error_code(EPERM, std::system_category()),
542 "shared_lock::unlock: not locked");
548template <
class Mutex>
562#include <shared_mutex>
566using std::shared_lock;
573#ifndef USE_THIRDPARTY_SHARED_MUTEX
574# if defined(_MSC_VER) && _MSVC_LANG < 202302L
575# pragma message("warning: USE_THIRDPARTY_SHARED_MUTEX not defined. By default use framework version.")
577# warning "USE_THIRDPARTY_SHARED_MUTEX not defined. By default use framework version."
579# define USE_THIRDPARTY_SHARED_MUTEX 0
583#if defined(__has_include) && __has_include(<version>) && !defined(__cpp_lib_shared_mutex) || \
585 (~USE_THIRDPARTY_SHARED_MUTEX + 1) || \
587 ( !(defined(__has_include) && __has_include(<version>)) && \
588 !(defined(HAVE_CXX17) && HAVE_CXX17) && __cplusplus < 201703 )
635using shared_mutex = detail::shared_mutex<detail::shared_mutex_type::PTHREAD_RWLOCK_PREFER_READER_NP>;
645#include <shared_mutex>
649using std::shared_mutex;
Definition shared_mutex.hpp:223
bool try_lock_shared()
Definition shared_mutex.hpp:273
void unlock_shared()
Definition shared_mutex.hpp:284
void lock_shared()
Definition shared_mutex.hpp:266
~debug_wrapper()
Definition shared_mutex.hpp:232
void unlock()
Definition shared_mutex.hpp:257
bool try_lock()
Definition shared_mutex.hpp:246
void lock()
Definition shared_mutex.hpp:239
void unlock_shared()
Definition shared_mutex.hpp:204
void lock()
Definition shared_mutex.hpp:192
void unlock_shared()
Definition shared_mutex.hpp:161
void lock()
Definition shared_mutex.hpp:147
Definition shared_mutex.hpp:52
shared_mutex_base & operator=(const shared_mutex_base &)=delete
shared_mutex_base(const shared_mutex_base &)=delete
bool try_lock_shared()
Definition shared_mutex.hpp:118
void lock_shared()
Definition shared_mutex.hpp:106
~shared_mutex_base()
Definition shared_mutex.hpp:74
static const count_t n_readers_
Definition shared_mutex.hpp:65
void unlock()
Definition shared_mutex.hpp:97
count_t state_
Definition shared_mutex.hpp:62
unsigned count_t
Definition shared_mutex.hpp:58
bool try_lock()
Definition shared_mutex.hpp:86
std::condition_variable cond_t
Definition shared_mutex.hpp:57
static const count_t write_entered_
Definition shared_mutex.hpp:64
mutex_t mut_
Definition shared_mutex.hpp:60
std::mutex mutex_t
Definition shared_mutex.hpp:56
cond_t gate1_
Definition shared_mutex.hpp:61
shared_mutex_base()
Definition shared_mutex.hpp:69
Definition shared_mutex.hpp:135
Definition shared_mutex.hpp:314
mutex_type * release()
Definition shared_mutex.hpp:456
mutex_type * mutex() const
Definition shared_mutex.hpp:472
shared_lock(mutex_type &m, const std::chrono::duration< Rep, Period > &rel_time)
Definition shared_mutex.hpp:379
bool try_lock_until(const std::chrono::time_point< Clock, Duration > &abs_time)
Definition shared_mutex.hpp:518
shared_lock(shared_lock &&sl)
Definition shared_mutex.hpp:400
void swap(shared_lock &&u)
Definition shared_mutex.hpp:449
shared_lock & operator=(shared_lock const &)=delete
shared_lock(mutex_type &m)
Definition shared_mutex.hpp:337
Mutex mutex_type
Definition shared_mutex.hpp:317
shared_lock()
Definition shared_mutex.hpp:331
bool try_lock_for(const std::chrono::duration< Rep, Period > &rel_time)
Definition shared_mutex.hpp:437
shared_lock(std::unique_lock< mutex_type > &&ul)
Definition shared_mutex.hpp:422
shared_lock(mutex_type &m, std::adopt_lock_t)
Definition shared_mutex.hpp:361
void unlock()
Definition shared_mutex.hpp:537
shared_lock(shared_lock const &)=delete
bool try_lock()
Definition shared_mutex.hpp:499
void lock()
Definition shared_mutex.hpp:481
shared_lock(mutex_type &m, std::try_to_lock_t)
Definition shared_mutex.hpp:353
shared_lock(mutex_type &m, const std::chrono::time_point< Clock, Duration > &abs_time)
Definition shared_mutex.hpp:370
bool owns_lock() const
Definition shared_mutex.hpp:464
shared_lock(mutex_type &m, std::defer_lock_t)
Definition shared_mutex.hpp:345
~shared_lock()
Definition shared_mutex.hpp:387
shared_mutex_type
Definition shared_mutex.hpp:47
@ PTHREAD_RWLOCK_PREFER_READER_NP
@ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
eProsima namespace.
Definition LibrarySettingsAttributes.h:23
detail::debug_wrapper< detail::shared_mutex< detail::shared_mutex_type::PTHREAD_RWLOCK_PREFER_READER_NP > > shared_mutex
Definition shared_mutex.hpp:638
void swap(shared_lock< Mutex > &x, shared_lock< Mutex > &y)
Definition shared_mutex.hpp:551