Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:35:05

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2015.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   locks.hpp
0009  * \author Andrey Semashev
0010  * \date   30.05.2010
0011  *
0012  * \brief  This header is the Boost.Log library implementation, see the library documentation
0013  *         at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
0014  */
0015 
0016 #ifndef BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
0017 #define BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
0018 
0019 #include <boost/log/detail/config.hpp>
0020 
0021 #ifndef BOOST_LOG_NO_THREADS
0022 
0023 #include <boost/move/detail/std_ns_begin.hpp>
0024 BOOST_MOVE_STD_NS_BEG
0025 
0026 // Forward declaration of the standard locks. Specified to avoid including <mutex> and <shared_mutex>.
0027 #if !defined(BOOST_MSSTL_VERSION) || (BOOST_MSSTL_VERSION != 140)
0028 template< typename >
0029 class lock_guard;
0030 #else
0031 // MSVC 14.0 has a non-confogrming lock_guard
0032 template< typename... >
0033 class lock_guard;
0034 #endif
0035 template< typename >
0036 class unique_lock;
0037 #if !defined(BOOST_NO_CXX14_HDR_SHARED_MUTEX)
0038 template< typename >
0039 class shared_lock;
0040 #endif
0041 #if defined(__cpp_lib_scoped_lock) && (__cpp_lib_scoped_lock >= 201703l)
0042 template< typename... >
0043 class scoped_lock;
0044 #endif
0045 
0046 BOOST_MOVE_STD_NS_END
0047 #include <boost/move/detail/std_ns_end.hpp>
0048 
0049 #endif // BOOST_LOG_NO_THREADS
0050 
0051 #include <boost/log/detail/header.hpp>
0052 
0053 #ifdef BOOST_HAS_PRAGMA_ONCE
0054 #pragma once
0055 #endif
0056 
0057 namespace boost {
0058 
0059 #ifndef BOOST_LOG_NO_THREADS
0060 
0061 // Forward declaration of Boost.Thread locks. Specified here to avoid including Boost.Thread,
0062 // which would bring in many dependent headers, including a great deal of Boost.DateTime.
0063 template< typename >
0064 class lock_guard;
0065 template< typename >
0066 class shared_lock_guard;
0067 template< typename >
0068 class shared_lock;
0069 template< typename >
0070 class upgrade_lock;
0071 template< typename >
0072 class unique_lock;
0073 
0074 template< typename >
0075 struct is_mutex_type;
0076 
0077 #endif // BOOST_LOG_NO_THREADS
0078 
0079 BOOST_LOG_OPEN_NAMESPACE
0080 
0081 //! An auxiliary pseudo-lock to express no locking requirements in logger features
0082 template< typename MutexT >
0083 class no_lock
0084 {
0085 public:
0086     /*!
0087      * Constructs the pseudo-lock. The mutex is not affected during the construction.
0088      */
0089     explicit no_lock(MutexT&) BOOST_NOEXCEPT {}
0090 
0091 private:
0092     no_lock(no_lock const&);
0093     no_lock& operator= (no_lock const&);
0094 };
0095 
0096 namespace aux {
0097 
0098 #ifndef BOOST_LOG_NO_THREADS
0099 
0100 //! A trait to detect if the mutex supports exclusive locking
0101 template< typename MutexT >
0102 struct is_exclusively_lockable
0103 {
0104     typedef char true_type;
0105     struct false_type { char t[2]; };
0106 
0107     template< typename T >
0108     static true_type check_lockable(T*, void (T::*)() = &T::lock, void (T::*)() = &T::unlock);
0109     static false_type check_lockable(void*);
0110 
0111     enum value_t { value = sizeof(check_lockable((MutexT*)NULL)) == sizeof(true_type) };
0112 };
0113 
0114 //! A trait to detect if the mutex supports shared locking
0115 template< typename MutexT >
0116 struct is_shared_lockable
0117 {
0118     typedef char true_type;
0119     struct false_type { char t[2]; };
0120 
0121     template< typename T >
0122     static true_type check_shared_lockable(T*, void (T::*)() = &T::lock_shared, void (T::*)() = &T::unlock_shared);
0123     static false_type check_shared_lockable(void*);
0124 
0125     enum value_t { value = sizeof(check_shared_lockable((MutexT*)NULL)) == sizeof(true_type) };
0126 };
0127 
0128 //! A scope guard that automatically unlocks the mutex on destruction
0129 template< typename MutexT >
0130 struct exclusive_auto_unlocker
0131 {
0132     explicit exclusive_auto_unlocker(MutexT& m) BOOST_NOEXCEPT : m_Mutex(m)
0133     {
0134     }
0135     ~exclusive_auto_unlocker()
0136     {
0137         m_Mutex.unlock();
0138     }
0139 
0140     BOOST_DELETED_FUNCTION(exclusive_auto_unlocker(exclusive_auto_unlocker const&))
0141     BOOST_DELETED_FUNCTION(exclusive_auto_unlocker& operator= (exclusive_auto_unlocker const&))
0142 
0143 protected:
0144     MutexT& m_Mutex;
0145 };
0146 
0147 //! An analogue to the minimalistic \c lock_guard template. Defined here to avoid including Boost.Thread.
0148 template< typename MutexT >
0149 struct exclusive_lock_guard
0150 {
0151     explicit exclusive_lock_guard(MutexT& m) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m.lock())) : m_Mutex(m)
0152     {
0153         m.lock();
0154     }
0155     ~exclusive_lock_guard()
0156     {
0157         m_Mutex.unlock();
0158     }
0159 
0160     BOOST_DELETED_FUNCTION(exclusive_lock_guard(exclusive_lock_guard const&))
0161     BOOST_DELETED_FUNCTION(exclusive_lock_guard& operator= (exclusive_lock_guard const&))
0162 
0163 private:
0164     MutexT& m_Mutex;
0165 };
0166 
0167 //! An analogue to the minimalistic \c lock_guard template that locks \c shared_mutex with shared ownership.
0168 template< typename MutexT >
0169 struct shared_lock_guard
0170 {
0171     explicit shared_lock_guard(MutexT& m) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m.lock_shared())) : m_Mutex(m)
0172     {
0173         m.lock_shared();
0174     }
0175     ~shared_lock_guard()
0176     {
0177         m_Mutex.unlock_shared();
0178     }
0179 
0180     BOOST_DELETED_FUNCTION(shared_lock_guard(shared_lock_guard const&))
0181     BOOST_DELETED_FUNCTION(shared_lock_guard& operator= (shared_lock_guard const&))
0182 
0183 private:
0184     MutexT& m_Mutex;
0185 };
0186 
0187 //! A deadlock-safe lock type that exclusively locks two mutexes
0188 template< typename MutexT1, typename MutexT2 >
0189 class multiple_unique_lock2
0190 {
0191 public:
0192     multiple_unique_lock2(MutexT1& m1, MutexT2& m2) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.lock()) && BOOST_NOEXCEPT_EXPR(m2.lock())) :
0193         m_p1(&m1),
0194         m_p2(&m2)
0195     {
0196         // Yes, it's not conforming, but it works
0197         // and it doesn't require to #include <functional>
0198         if (static_cast< void* >(m_p1) < static_cast< void* >(m_p2))
0199         {
0200             m_p1->lock();
0201             m_p2->lock();
0202         }
0203         else
0204         {
0205             m_p2->lock();
0206             m_p1->lock();
0207         }
0208     }
0209     ~multiple_unique_lock2()
0210     {
0211         m_p2->unlock();
0212         m_p1->unlock();
0213     }
0214 
0215 private:
0216     MutexT1* m_p1;
0217     MutexT2* m_p2;
0218 };
0219 
0220 #endif // BOOST_LOG_NO_THREADS
0221 
0222 } // namespace aux
0223 
0224 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0225 
0226 } // namespace boost
0227 
0228 #include <boost/log/detail/footer.hpp>
0229 
0230 #endif // BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_