Back to home page

EIC code displayed by LXR

 
 

    


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 // Copyright 2023 Christian Mazakas.
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // https://www.boost.org/LICENSE_1_0.txt
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 } // namespace compat
0129 } // namespace boost
0130 
0131 #endif // BOOST_COMPAT_SHARED_LOCK_HPP_INCLUDED