Mercurial > hg > vamp-build-and-test
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 |