comparison DEPENDENCIES/generic/include/boost/log/detail/locking_ptr.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
1 /* 1 /*
2 * Copyright Andrey Semashev 2007 - 2013. 2 * Copyright Andrey Semashev 2007 - 2015.
3 * Distributed under the Boost Software License, Version 1.0. 3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at 4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt) 5 * http://www.boost.org/LICENSE_1_0.txt)
6 */ 6 */
7 /*! 7 /*!
14 */ 14 */
15 15
16 #ifndef BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_ 16 #ifndef BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_
17 #define BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_ 17 #define BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_
18 18
19 #include <cstddef>
20 #include <boost/move/core.hpp>
19 #include <boost/smart_ptr/shared_ptr.hpp> 21 #include <boost/smart_ptr/shared_ptr.hpp>
22 #include <boost/thread/lock_options.hpp>
20 #include <boost/log/detail/config.hpp> 23 #include <boost/log/detail/config.hpp>
21 #include <boost/utility/explicit_operator_bool.hpp> 24 #include <boost/utility/explicit_operator_bool.hpp>
22 #include <boost/log/detail/header.hpp> 25 #include <boost/log/detail/header.hpp>
23 26
24 #ifdef BOOST_HAS_PRAGMA_ONCE 27 #ifdef BOOST_HAS_PRAGMA_ONCE
29 32
30 BOOST_LOG_OPEN_NAMESPACE 33 BOOST_LOG_OPEN_NAMESPACE
31 34
32 namespace aux { 35 namespace aux {
33 36
34 //! Shared lock object to support locking_ptr
35 struct BOOST_LOG_NO_VTABLE locking_ptr_counter_base
36 {
37 unsigned int m_RefCounter;
38
39 locking_ptr_counter_base() : m_RefCounter(0)
40 {
41 }
42
43 virtual ~locking_ptr_counter_base() {}
44 virtual void lock() = 0;
45 virtual bool try_lock() = 0;
46 virtual void unlock() = 0;
47
48 private:
49 locking_ptr_counter_base(locking_ptr_counter_base const&);
50 locking_ptr_counter_base& operator= (locking_ptr_counter_base const&);
51 };
52
53 struct try_lock_tag {};
54 BOOST_CONSTEXPR_OR_CONST try_lock_tag try_lock = {};
55
56 //! A pointer type that locks the backend until it's destroyed 37 //! A pointer type that locks the backend until it's destroyed
57 template< typename T > 38 template< typename T, typename LockableT >
58 class locking_ptr 39 class locking_ptr
59 { 40 {
41 typedef locking_ptr this_type;
42 BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
43
60 public: 44 public:
61 //! Pointed type 45 //! Pointed type
62 typedef T element_type; 46 typedef T element_type;
63 47
64 private: 48 private:
49 //! Lockable type
50 typedef LockableT lockable_type;
51
52 private:
65 //! The pointer to the backend 53 //! The pointer to the backend
66 shared_ptr< element_type > m_pElement; 54 shared_ptr< element_type > m_pElement;
67 //! Reference to the shared lock control object 55 //! Reference to the shared lock control object
68 locking_ptr_counter_base* m_pLock; 56 lockable_type* m_pLock;
69 57
70 public: 58 public:
71 //! Constructor 59 //! Default constructor
72 locking_ptr(shared_ptr< element_type > const& p, locking_ptr_counter_base& l) 60 locking_ptr() BOOST_NOEXCEPT : m_pLock(NULL)
73 : m_pElement(p), m_pLock(&l)
74 { 61 {
75 if (m_pLock->m_RefCounter == 0)
76 m_pLock->lock();
77 ++m_pLock->m_RefCounter;
78 } 62 }
79 //! Constructor 63 //! Constructor
80 locking_ptr(shared_ptr< element_type > const& p, locking_ptr_counter_base& l, try_lock_tag const&) 64 locking_ptr(shared_ptr< element_type > const& p, lockable_type& l) : m_pElement(p), m_pLock(&l)
81 : m_pElement(p), m_pLock(&l)
82 { 65 {
83 if (m_pLock->m_RefCounter > 0 || m_pLock->try_lock()) 66 m_pLock->lock();
84 { 67 }
85 ++m_pLock->m_RefCounter; 68 //! Constructor
86 } 69 locking_ptr(shared_ptr< element_type > const& p, lockable_type& l, try_to_lock_t const&) : m_pElement(p), m_pLock(&l)
87 else 70 {
71 if (!m_pLock->try_lock())
88 { 72 {
89 m_pElement.reset(); 73 m_pElement.reset();
90 m_pLock = NULL; 74 m_pLock = NULL;
91 } 75 }
92 } 76 }
93 //! Copy constructor 77 //! Copy constructor
94 locking_ptr(locking_ptr const& that) : m_pElement(that.m_pElement), m_pLock(that.m_pLock) 78 locking_ptr(locking_ptr const& that) : m_pElement(that.m_pElement), m_pLock(that.m_pLock)
95 { 79 {
96 if (m_pLock) 80 if (m_pLock)
97 ++m_pLock->m_RefCounter; 81 m_pLock->lock();
98 } 82 }
83 //! Move constructor
84 locking_ptr(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT : m_pLock(that.m_pLock)
85 {
86 m_pElement.swap(that.m_pElement);
87 that.m_pLock = NULL;
88 }
89
99 //! Destructor 90 //! Destructor
100 ~locking_ptr() 91 ~locking_ptr()
101 { 92 {
102 if (m_pLock && --m_pLock->m_RefCounter == 0) 93 if (m_pLock)
103 m_pLock->unlock(); 94 m_pLock->unlock();
104 } 95 }
105 96
106 //! Assignment 97 //! Assignment
107 locking_ptr& operator= (locking_ptr that) 98 locking_ptr& operator= (locking_ptr that) BOOST_NOEXCEPT
108 { 99 {
109 this->swap(that); 100 this->swap(that);
110 return *this; 101 return *this;
111 } 102 }
112 103
113 //! Indirection 104 //! Indirection
114 element_type* operator-> () const { return m_pElement.get(); } 105 element_type* operator-> () const BOOST_NOEXCEPT { return m_pElement.get(); }
115 //! Dereferencing 106 //! Dereferencing
116 element_type& operator* () const { return *m_pElement; } 107 element_type& operator* () const BOOST_NOEXCEPT { return *m_pElement; }
117 108
118 //! Accessor to the raw pointer 109 //! Accessor to the raw pointer
119 element_type* get() const { return m_pElement.get(); } 110 element_type* get() const BOOST_NOEXCEPT { return m_pElement.get(); }
120 111
121 //! Checks for null pointer 112 //! Checks for null pointer
122 BOOST_EXPLICIT_OPERATOR_BOOL() 113 BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
123 //! Checks for null pointer 114 //! Checks for null pointer
124 bool operator! () const { return !m_pElement; } 115 bool operator! () const BOOST_NOEXCEPT { return !m_pElement; }
125 116
126 //! Swaps two pointers 117 //! Swaps two pointers
127 void swap(locking_ptr& that) 118 void swap(locking_ptr& that) BOOST_NOEXCEPT
128 { 119 {
129 m_pElement.swap(that.m_pElement); 120 m_pElement.swap(that.m_pElement);
130 register locking_ptr_counter_base* p = m_pLock; 121 lockable_type* p = m_pLock;
131 m_pLock = that.m_pLock; 122 m_pLock = that.m_pLock;
132 that.m_pLock = p; 123 that.m_pLock = p;
133 } 124 }
134 }; 125 };
135 126
136 //! Free raw pointer getter to assist generic programming 127 //! Free raw pointer getter to assist generic programming
137 template< typename T > 128 template< typename T, typename LockableT >
138 inline T* get_pointer(locking_ptr< T > const& p) 129 inline T* get_pointer(locking_ptr< T, LockableT > const& p) BOOST_NOEXCEPT
139 { 130 {
140 return p.get(); 131 return p.get();
141 } 132 }
142 //! Free swap operation 133 //! Free swap operation
143 template< typename T > 134 template< typename T, typename LockableT >
144 inline void swap(locking_ptr< T >& left, locking_ptr< T >& right) 135 inline void swap(locking_ptr< T, LockableT >& left, locking_ptr< T, LockableT >& right) BOOST_NOEXCEPT
145 { 136 {
146 left.swap(right); 137 left.swap(right);
147 } 138 }
148 139
149 } // namespace aux 140 } // namespace aux