File indexing completed on 2025-01-18 09:29:53
0001 #ifndef BOOST_COMPAT_SHARED_LOCK_HPP_INCLUDED
0002 #define BOOST_COMPAT_SHARED_LOCK_HPP_INCLUDED
0003
0004
0005
0006
0007
0008 #include <boost/compat/detail/throw_system_error.hpp>
0009
0010 #include <memory> // std::addressof
0011 #include <mutex> // std::defer_lock_t
0012 #include <system_error> // std::errc
0013
0014 namespace boost {
0015 namespace compat {
0016
0017 template <class Mutex>
0018 class shared_lock;
0019
0020 template <class Mutex>
0021 void swap( shared_lock<Mutex>& x, shared_lock<Mutex>& y ) noexcept;
0022
0023 template <class Mutex>
0024 class shared_lock {
0025 private:
0026 Mutex* pm_ = nullptr;
0027 bool owns_ = false;
0028
0029 public:
0030 using mutex_type = Mutex;
0031
0032 shared_lock() noexcept = default;
0033
0034 explicit shared_lock( mutex_type& m ) : pm_( std::addressof( m ) ) { lock(); }
0035
0036 shared_lock( mutex_type& m, std::defer_lock_t ) noexcept
0037 : pm_( std::addressof( m ) ) {}
0038
0039 shared_lock( mutex_type& m, std::try_to_lock_t )
0040 : pm_( std::addressof( m ) ) {
0041 try_lock();
0042 }
0043
0044 shared_lock( mutex_type& m, std::adopt_lock_t )
0045 : pm_( std::addressof( m ) ), owns_{ true } {}
0046
0047 ~shared_lock() {
0048 if ( owns_ ) {
0049 unlock();
0050 }
0051 }
0052
0053 shared_lock( const shared_lock& ) = delete;
0054 shared_lock& operator=( const shared_lock& ) = delete;
0055
0056 shared_lock( shared_lock&& u ) noexcept {
0057 pm_ = u.pm_;
0058 owns_ = u.owns_;
0059
0060 u.pm_ = nullptr;
0061 u.owns_ = false;
0062 }
0063
0064 shared_lock& operator=( shared_lock&& u ) noexcept {
0065 shared_lock( std::move( u ) ).swap( *this );
0066 return *this;
0067 }
0068
0069 void lock() {
0070 if ( !pm_ ) {
0071 detail::throw_system_error( std::errc::operation_not_permitted );
0072 }
0073
0074 if ( owns_lock() ) {
0075 detail::throw_system_error( std::errc::resource_deadlock_would_occur );
0076 }
0077
0078 pm_->lock_shared();
0079 owns_ = true;
0080 }
0081
0082 bool try_lock() {
0083 if ( !pm_ ) {
0084 detail::throw_system_error( std::errc::operation_not_permitted );
0085 }
0086
0087 if ( owns_lock() ) {
0088 detail::throw_system_error( std::errc::resource_deadlock_would_occur );
0089 }
0090
0091 bool b = pm_->try_lock_shared();
0092 owns_ = b;
0093 return b;
0094 }
0095
0096 void unlock() {
0097 if ( !pm_ || !owns_ ) {
0098 detail::throw_system_error( std::errc::operation_not_permitted );
0099 }
0100
0101 pm_->unlock_shared();
0102 owns_ = false;
0103 }
0104
0105 void swap( shared_lock& u ) noexcept {
0106 std::swap( pm_, u.pm_ );
0107 std::swap( owns_, u.owns_ );
0108 }
0109
0110 mutex_type* release() noexcept {
0111 mutex_type* pm = pm_;
0112 pm_ = nullptr;
0113 owns_ = false;
0114 return pm;
0115 }
0116
0117 mutex_type* mutex() const noexcept { return pm_; }
0118
0119 bool owns_lock() const noexcept { return owns_; }
0120 explicit operator bool() const noexcept { return owns_; }
0121 };
0122
0123 template <class Mutex>
0124 void swap( shared_lock<Mutex>& x, shared_lock<Mutex>& y ) noexcept {
0125 x.swap( y );
0126 }
0127
0128 }
0129 }
0130
0131 #endif