Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:43:04

0001 //
0002 // detail/conditionally_enabled_mutex.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
0012 #define BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/mutex.hpp>
0020 #include <boost/asio/detail/noncopyable.hpp>
0021 #include <boost/asio/detail/scoped_lock.hpp>
0022 
0023 #include <boost/asio/detail/push_options.hpp>
0024 
0025 namespace boost {
0026 namespace asio {
0027 namespace detail {
0028 
0029 // Mutex adapter used to conditionally enable or disable locking.
0030 class conditionally_enabled_mutex
0031   : private noncopyable
0032 {
0033 public:
0034   // Helper class to lock and unlock a mutex automatically.
0035   class scoped_lock
0036     : private noncopyable
0037   {
0038   public:
0039     // Tag type used to distinguish constructors.
0040     enum adopt_lock_t { adopt_lock };
0041 
0042     // Constructor adopts a lock that is already held.
0043     scoped_lock(conditionally_enabled_mutex& m, adopt_lock_t)
0044       : mutex_(m),
0045         locked_(m.enabled_)
0046     {
0047     }
0048 
0049     // Constructor acquires the lock.
0050     explicit scoped_lock(conditionally_enabled_mutex& m)
0051       : mutex_(m)
0052     {
0053       if (m.enabled_)
0054       {
0055         mutex_.mutex_.lock();
0056         locked_ = true;
0057       }
0058       else
0059         locked_ = false;
0060     }
0061 
0062     // Destructor releases the lock.
0063     ~scoped_lock()
0064     {
0065       if (locked_)
0066         mutex_.mutex_.unlock();
0067     }
0068 
0069     // Explicitly acquire the lock.
0070     void lock()
0071     {
0072       if (mutex_.enabled_ && !locked_)
0073       {
0074         for (int n = mutex_.spin_count_; n != 0; n -= (n > 0) ? 1 : 0)
0075         {
0076           if (mutex_.mutex_.try_lock())
0077           {
0078             locked_ = true;
0079             return;
0080           }
0081         }
0082         mutex_.mutex_.lock();
0083         locked_ = true;
0084       }
0085     }
0086 
0087     // Explicitly release the lock.
0088     void unlock()
0089     {
0090       if (locked_)
0091       {
0092         mutex_.unlock();
0093         locked_ = false;
0094       }
0095     }
0096 
0097     // Test whether the lock is held.
0098     bool locked() const
0099     {
0100       return locked_;
0101     }
0102 
0103     // Get the underlying mutex.
0104     boost::asio::detail::mutex& mutex()
0105     {
0106       return mutex_.mutex_;
0107     }
0108 
0109   private:
0110     friend class conditionally_enabled_event;
0111     conditionally_enabled_mutex& mutex_;
0112     bool locked_;
0113   };
0114 
0115   // Constructor.
0116   explicit conditionally_enabled_mutex(bool enabled, int spin_count = 0)
0117     : spin_count_(spin_count),
0118       enabled_(enabled)
0119   {
0120   }
0121 
0122   // Destructor.
0123   ~conditionally_enabled_mutex()
0124   {
0125   }
0126 
0127   // Determine whether locking is enabled.
0128   bool enabled() const
0129   {
0130     return enabled_;
0131   }
0132 
0133   // Get the spin count.
0134   int spin_count() const
0135   {
0136     return spin_count_;
0137   }
0138 
0139   // Lock the mutex.
0140   void lock()
0141   {
0142     if (enabled_)
0143     {
0144       for (int n = spin_count_; n != 0; n -= (n > 0) ? 1 : 0)
0145         if (mutex_.try_lock())
0146           return;
0147       mutex_.lock();
0148     }
0149   }
0150 
0151   // Unlock the mutex.
0152   void unlock()
0153   {
0154     if (enabled_)
0155       mutex_.unlock();
0156   }
0157 
0158 private:
0159   friend class scoped_lock;
0160   friend class conditionally_enabled_event;
0161   boost::asio::detail::mutex mutex_;
0162   const int spin_count_;
0163   const bool enabled_;
0164 };
0165 
0166 } // namespace detail
0167 } // namespace asio
0168 } // namespace boost
0169 
0170 #include <boost/asio/detail/pop_options.hpp>
0171 
0172 #endif // BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP