8#ifndef _UTILS_SHARED_MUTEX_HPP_
9#define _UTILS_SHARED_MUTEX_HPP_
11#ifndef USE_THIRDPARTY_SHARED_MUTEX
12# if defined(_MSC_VER) && _MSVC_LANG < 202302L
13# pragma message("warning: USE_THIRDPARTY_SHARED_MUTEX not defined. By default use framework version.")
15# warning "USE_THIRDPARTY_SHARED_MUTEX not defined. By default use framework version."
17# define USE_THIRDPARTY_SHARED_MUTEX 0
20#if defined(__has_include) && __has_include(<version>)
25#if defined(__has_include) && __has_include(<version>) && !defined(__cpp_lib_shared_mutex) || \
27 (~USE_THIRDPARTY_SHARED_MUTEX + 1) || \
29 ( !(defined(__has_include) && __has_include(<version>)) && \
30 !(defined(HAVE_CXX17) && HAVE_CXX17) && __cplusplus < 201703 )
33#include <condition_variable>
35#include <system_error>
41 typedef std::mutex mutex_t;
42 typedef std::condition_variable cond_t;
43 typedef unsigned count_t;
50 static const count_t write_entered_ = 1U << (
sizeof(count_t) * CHAR_BIT - 1);
51 static const count_t n_readers_ = ~write_entered_;
62 std::lock_guard<mutex_t> _(mut_);
74 std::unique_lock<mutex_t> lk(mut_);
75 while (state_ & write_entered_)
79 state_ |= write_entered_;
80 while (state_ & n_readers_)
88 std::unique_lock<mutex_t> lk(mut_);
91 state_ = write_entered_;
99 std::lock_guard<mutex_t> _(mut_);
108 std::unique_lock<mutex_t> lk(mut_);
109 while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
113 count_t num_readers = (state_ & n_readers_) + 1;
114 state_ &= ~n_readers_;
115 state_ |= num_readers;
120 std::unique_lock<mutex_t> lk(mut_);
121 count_t num_readers = state_ & n_readers_;
122 if (!(state_ & write_entered_) && num_readers != n_readers_)
125 state_ &= ~n_readers_;
126 state_ |= num_readers;
134 std::lock_guard<mutex_t> _(mut_);
135 count_t num_readers = (state_ & n_readers_) - 1;
136 state_ &= ~n_readers_;
137 state_ |= num_readers;
138 if (state_ & write_entered_)
140 if (num_readers == 0)
147 if (num_readers == n_readers_ - 1)
156template <
class Mutex>
201 , owns_(m.try_lock_shared())
213 template <
class Clock,
class Duration>
216 const std::chrono::time_point<Clock, Duration>& abs_time)
218 , owns_(m.try_lock_shared_until(abs_time))
222 template <
class Rep,
class Period>
225 const std::chrono::duration<Rep, Period>& rel_time)
227 , owns_(m.try_lock_shared_for(rel_time))
249 sl.m_ =
nullptr; sl.owns_ =
false;
267 std::unique_lock<mutex_type>&& ul)
273 m_->unlock_and_lock_shared();
280 template <
class Rep,
class Period>
282 const std::chrono::duration<Rep, Period>& rel_time)
284 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
287 template <
class Clock,
class Duration>
290 const std::chrono::time_point<Clock, Duration>& abs_time);
297 std::swap(owns_, u.owns_);
313 operator int __nat::* ()
const {
314 return owns_ ? &__nat::_ : 0;
323template <
class Mutex>
329 throw std::system_error(std::error_code(EPERM, std::system_category()),
330 "shared_lock::lock: references null mutex");
334 throw std::system_error(std::error_code(EDEADLK, std::system_category()),
335 "shared_lock::lock: already locked");
341template <
class Mutex>
347 throw std::system_error(std::error_code(EPERM, std::system_category()),
348 "shared_lock::try_lock: references null mutex");
352 throw std::system_error(std::error_code(EDEADLK, std::system_category()),
353 "shared_lock::try_lock: already locked");
355 owns_ = m_->try_lock_shared();
363#include <shared_mutex>
367using std::shared_mutex;
368using std::shared_lock;
Definition: shared_mutex.hpp:158
mutex_type * release()
Definition: shared_mutex.hpp:300
mutex_type * mutex() const
Definition: shared_mutex.hpp:316
shared_lock(mutex_type &m, const std::chrono::duration< Rep, Period > &rel_time)
Definition: shared_mutex.hpp:223
bool try_lock_until(const std::chrono::time_point< Clock, Duration > &abs_time)
shared_lock(shared_lock &&sl)
Definition: shared_mutex.hpp:244
void swap(shared_lock &&u)
Definition: shared_mutex.hpp:293
shared_lock & operator=(shared_lock const &)=delete
shared_lock(mutex_type &m)
Definition: shared_mutex.hpp:181
Mutex mutex_type
Definition: shared_mutex.hpp:161
shared_lock()
Definition: shared_mutex.hpp:175
bool try_lock_for(const std::chrono::duration< Rep, Period > &rel_time)
Definition: shared_mutex.hpp:281
shared_lock(std::unique_lock< mutex_type > &&ul)
Definition: shared_mutex.hpp:266
shared_lock(mutex_type &m, std::adopt_lock_t)
Definition: shared_mutex.hpp:205
shared_lock(shared_lock const &)=delete
bool try_lock()
Definition: shared_mutex.hpp:343
void lock()
Definition: shared_mutex.hpp:325
shared_lock(mutex_type &m, std::try_to_lock_t)
Definition: shared_mutex.hpp:197
shared_lock(mutex_type &m, const std::chrono::time_point< Clock, Duration > &abs_time)
Definition: shared_mutex.hpp:214
bool owns_lock() const
Definition: shared_mutex.hpp:308
shared_lock(mutex_type &m, std::defer_lock_t)
Definition: shared_mutex.hpp:189
~shared_lock()
Definition: shared_mutex.hpp:231
Definition: shared_mutex.hpp:40
bool try_lock_shared()
Definition: shared_mutex.hpp:118
~shared_mutex()
Definition: shared_mutex.hpp:60
void unlock_shared()
Definition: shared_mutex.hpp:132
void lock_shared()
Definition: shared_mutex.hpp:106
shared_mutex()
Definition: shared_mutex.hpp:55
shared_mutex(const shared_mutex &)=delete
void unlock()
Definition: shared_mutex.hpp:97
bool try_lock()
Definition: shared_mutex.hpp:86
void lock()
Definition: shared_mutex.hpp:72
shared_mutex & operator=(const shared_mutex &)=delete
eProsima namespace.
Definition: LibrarySettingsAttributes.h:23