1 #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED 2 #define BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED 3 4 // 5 // atomic_shared_ptr.hpp 6 // 7 // Copyright 2017 Peter Dimov 8 // 9 // Distributed under the Boost Software License, Version 1.0. (See 10 // accompanying file LICENSE_1_0.txt or copy at 11 // http://www.boost.org/LICENSE_1_0.txt) 12 // 13 // See http://www.boost.org/libs/smart_ptr/ for documentation. 14 // 15 16 #include <boost/smart_ptr/shared_ptr.hpp> 17 #include <boost/smart_ptr/detail/spinlock.hpp> 18 #include <cstring> 19 20 namespace boost 21 { 22 23 template<class T> class atomic_shared_ptr 24 { 25 private: 26 27 boost::shared_ptr<T> p_; 28 29 mutable boost::detail::spinlock l_; 30 31 atomic_shared_ptr(const atomic_shared_ptr&); 32 atomic_shared_ptr& operator=(const atomic_shared_ptr&); 33 34 private: 35 compare_exchange(shared_ptr<T> & v,shared_ptr<T> w)36 bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT 37 { 38 l_.lock(); 39 40 if( p_._internal_equiv( v ) ) 41 { 42 p_.swap( w ); 43 44 l_.unlock(); 45 return true; 46 } 47 else 48 { 49 shared_ptr<T> tmp( p_ ); 50 51 l_.unlock(); 52 53 tmp.swap( v ); 54 return false; 55 } 56 } 57 58 public: 59 60 #if !defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX ) && !defined( BOOST_NO_CXX11_CONSTEXPR ) 61 atomic_shared_ptr()62 constexpr atomic_shared_ptr() BOOST_SP_NOEXCEPT: l_ BOOST_DETAIL_SPINLOCK_INIT 63 { 64 } 65 atomic_shared_ptr(shared_ptr<T> p)66 atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT 67 : p_( std::move( p ) ), l_ BOOST_DETAIL_SPINLOCK_INIT 68 { 69 } 70 71 #else 72 73 atomic_shared_ptr() BOOST_SP_NOEXCEPT 74 { 75 boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT; 76 std::memcpy( &l_, &init, sizeof( init ) ); 77 } 78 79 atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT 80 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) 81 : p_( std::move( p ) ) 82 #else 83 : p_( p ) 84 #endif 85 { 86 boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT; 87 std::memcpy( &l_, &init, sizeof( init ) ); 88 } 89 90 #endif 91 operator =(shared_ptr<T> r)92 atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT 93 { 94 boost::detail::spinlock::scoped_lock lock( l_ ); 95 p_.swap( r ); 96 97 return *this; 98 } 99 is_lock_free() const100 BOOST_CONSTEXPR bool is_lock_free() const BOOST_SP_NOEXCEPT 101 { 102 return false; 103 } 104 load() const105 shared_ptr<T> load() const BOOST_SP_NOEXCEPT 106 { 107 boost::detail::spinlock::scoped_lock lock( l_ ); 108 return p_; 109 } 110 load(M) const111 template<class M> shared_ptr<T> load( M ) const BOOST_SP_NOEXCEPT 112 { 113 boost::detail::spinlock::scoped_lock lock( l_ ); 114 return p_; 115 } 116 operator shared_ptr<T>() const117 operator shared_ptr<T>() const BOOST_SP_NOEXCEPT 118 { 119 boost::detail::spinlock::scoped_lock lock( l_ ); 120 return p_; 121 } 122 store(shared_ptr<T> r)123 void store( shared_ptr<T> r ) BOOST_SP_NOEXCEPT 124 { 125 boost::detail::spinlock::scoped_lock lock( l_ ); 126 p_.swap( r ); 127 } 128 store(shared_ptr<T> r,M)129 template<class M> void store( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT 130 { 131 boost::detail::spinlock::scoped_lock lock( l_ ); 132 p_.swap( r ); 133 } 134 exchange(shared_ptr<T> r)135 shared_ptr<T> exchange( shared_ptr<T> r ) BOOST_SP_NOEXCEPT 136 { 137 { 138 boost::detail::spinlock::scoped_lock lock( l_ ); 139 p_.swap( r ); 140 } 141 142 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) 143 144 return std::move( r ); 145 146 #else 147 148 return r; 149 150 #endif 151 } 152 exchange(shared_ptr<T> r,M)153 template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT 154 { 155 { 156 boost::detail::spinlock::scoped_lock lock( l_ ); 157 p_.swap( r ); 158 } 159 160 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) 161 162 return std::move( r ); 163 164 #else 165 166 return r; 167 168 #endif 169 } 170 compare_exchange_weak(shared_ptr<T> & v,const shared_ptr<T> & w,M,M)171 template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT 172 { 173 return compare_exchange( v, w ); 174 } 175 compare_exchange_weak(shared_ptr<T> & v,const shared_ptr<T> & w,M)176 template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT 177 { 178 return compare_exchange( v, w ); 179 } 180 compare_exchange_weak(shared_ptr<T> & v,const shared_ptr<T> & w)181 bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT 182 { 183 return compare_exchange( v, w ); 184 } 185 compare_exchange_strong(shared_ptr<T> & v,const shared_ptr<T> & w,M,M)186 template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT 187 { 188 return compare_exchange( v, w ); 189 } 190 compare_exchange_strong(shared_ptr<T> & v,const shared_ptr<T> & w,M)191 template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT 192 { 193 return compare_exchange( v, w ); 194 } 195 compare_exchange_strong(shared_ptr<T> & v,const shared_ptr<T> & w)196 bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT 197 { 198 return compare_exchange( v, w ); 199 } 200 201 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) 202 compare_exchange_weak(shared_ptr<T> & v,shared_ptr<T> && w,M,M)203 template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT 204 { 205 return compare_exchange( v, std::move( w ) ); 206 } 207 compare_exchange_weak(shared_ptr<T> & v,shared_ptr<T> && w,M)208 template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT 209 { 210 return compare_exchange( v, std::move( w ) ); 211 } 212 compare_exchange_weak(shared_ptr<T> & v,shared_ptr<T> && w)213 bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT 214 { 215 return compare_exchange( v, std::move( w ) ); 216 } 217 compare_exchange_strong(shared_ptr<T> & v,shared_ptr<T> && w,M,M)218 template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT 219 { 220 return compare_exchange( v, std::move( w ) ); 221 } 222 compare_exchange_strong(shared_ptr<T> & v,shared_ptr<T> && w,M)223 template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT 224 { 225 return compare_exchange( v, std::move( w ) ); 226 } 227 compare_exchange_strong(shared_ptr<T> & v,shared_ptr<T> && w)228 bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT 229 { 230 return compare_exchange( v, std::move( w ) ); 231 } 232 233 #endif 234 }; 235 236 } // namespace boost 237 238 #endif // #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED 239