Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:21

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   locking_ptr.hpp
0009  * \author Andrey Semashev
0010  * \date   15.07.2009
0011  *
0012  * 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_LOCKING_PTR_HPP_INCLUDED_
0017 #define BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_
0018 
0019 #include <cstddef>
0020 #include <boost/move/core.hpp>
0021 #include <boost/smart_ptr/shared_ptr.hpp>
0022 #include <boost/thread/lock_options.hpp>
0023 #include <boost/core/explicit_operator_bool.hpp>
0024 #include <boost/log/detail/config.hpp>
0025 #include <boost/log/detail/header.hpp>
0026 
0027 #ifdef BOOST_HAS_PRAGMA_ONCE
0028 #pragma once
0029 #endif
0030 
0031 namespace boost {
0032 
0033 BOOST_LOG_OPEN_NAMESPACE
0034 
0035 namespace aux {
0036 
0037 //! A pointer type that locks the backend until it's destroyed
0038 template< typename T, typename LockableT >
0039 class locking_ptr
0040 {
0041     typedef locking_ptr this_type;
0042     BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
0043 
0044 public:
0045     //! Pointed type
0046     typedef T element_type;
0047 
0048 private:
0049     //! Lockable type
0050     typedef LockableT lockable_type;
0051 
0052 private:
0053     //! The pointer to the backend
0054     shared_ptr< element_type > m_pElement;
0055     //! Reference to the shared lock control object
0056     lockable_type* m_pLock;
0057 
0058 public:
0059     //! Default constructor
0060     locking_ptr() BOOST_NOEXCEPT : m_pLock(NULL)
0061     {
0062     }
0063     //! Constructor
0064     locking_ptr(shared_ptr< element_type > const& p, lockable_type& l) : m_pElement(p), m_pLock(&l)
0065     {
0066         m_pLock->lock();
0067     }
0068     //! Constructor
0069     locking_ptr(shared_ptr< element_type > const& p, lockable_type& l, try_to_lock_t const&) : m_pElement(p), m_pLock(&l)
0070     {
0071         if (!m_pLock->try_lock())
0072         {
0073             m_pElement.reset();
0074             m_pLock = NULL;
0075         }
0076     }
0077     //! Copy constructor
0078     locking_ptr(locking_ptr const& that) : m_pElement(that.m_pElement), m_pLock(that.m_pLock)
0079     {
0080         if (m_pLock)
0081             m_pLock->lock();
0082     }
0083     //! Move constructor
0084     locking_ptr(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT : m_pLock(that.m_pLock)
0085     {
0086         m_pElement.swap(that.m_pElement);
0087         that.m_pLock = NULL;
0088     }
0089 
0090     //! Destructor
0091     ~locking_ptr()
0092     {
0093         if (m_pLock)
0094             m_pLock->unlock();
0095     }
0096 
0097     //! Assignment
0098     locking_ptr& operator= (locking_ptr that) BOOST_NOEXCEPT
0099     {
0100         this->swap(that);
0101         return *this;
0102     }
0103 
0104     //! Indirection
0105     element_type* operator-> () const BOOST_NOEXCEPT { return m_pElement.get(); }
0106     //! Dereferencing
0107     element_type& operator* () const BOOST_NOEXCEPT { return *m_pElement; }
0108 
0109     //! Accessor to the raw pointer
0110     element_type* get() const BOOST_NOEXCEPT { return m_pElement.get(); }
0111 
0112     //! Checks for null pointer
0113     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
0114     //! Checks for null pointer
0115     bool operator! () const BOOST_NOEXCEPT { return !m_pElement; }
0116 
0117     //! Swaps two pointers
0118     void swap(locking_ptr& that) BOOST_NOEXCEPT
0119     {
0120         m_pElement.swap(that.m_pElement);
0121         lockable_type* p = m_pLock;
0122         m_pLock = that.m_pLock;
0123         that.m_pLock = p;
0124     }
0125 };
0126 
0127 //! Free raw pointer getter to assist generic programming
0128 template< typename T, typename LockableT >
0129 inline T* get_pointer(locking_ptr< T, LockableT > const& p) BOOST_NOEXCEPT
0130 {
0131     return p.get();
0132 }
0133 //! Free swap operation
0134 template< typename T, typename LockableT >
0135 inline void swap(locking_ptr< T, LockableT >& left, locking_ptr< T, LockableT >& right) BOOST_NOEXCEPT
0136 {
0137     left.swap(right);
0138 }
0139 
0140 } // namespace aux
0141 
0142 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0143 
0144 } // namespace boost
0145 
0146 #include <boost/log/detail/footer.hpp>
0147 
0148 #endif // BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_