diff --git a/doc/smart_ptr/atomic_shared_ptr.adoc b/doc/smart_ptr/atomic_shared_ptr.adoc index 3c8d27e..5794711 100644 --- a/doc/smart_ptr/atomic_shared_ptr.adoc +++ b/doc/smart_ptr/atomic_shared_ptr.adoc @@ -36,7 +36,7 @@ namespace boost { public: atomic_shared_ptr() noexcept = default; - constexpr atomic_shared_ptr( shared_ptr p ) noexcept; + atomic_shared_ptr( shared_ptr p ) noexcept; atomic_shared_ptr& operator=( shared_ptr r ) noexcept; @@ -65,7 +65,7 @@ namespace boost { ## Members ``` -constexpr atomic_shared_ptr( shared_ptr p ) noexcept; +atomic_shared_ptr( shared_ptr p ) noexcept; ``` [none] * {blank} diff --git a/include/boost/smart_ptr/atomic_shared_ptr.hpp b/include/boost/smart_ptr/atomic_shared_ptr.hpp index fdc97bd..7590b67 100644 --- a/include/boost/smart_ptr/atomic_shared_ptr.hpp +++ b/include/boost/smart_ptr/atomic_shared_ptr.hpp @@ -14,6 +14,8 @@ // #include +#include +#include namespace boost { @@ -24,35 +26,59 @@ private: boost::shared_ptr p_; + mutable boost::detail::spinlock l_; + atomic_shared_ptr(const atomic_shared_ptr&); atomic_shared_ptr& operator=(const atomic_shared_ptr&); +private: + + bool compare_exchange( shared_ptr& v, shared_ptr w ) BOOST_SP_NOEXCEPT + { + l_.lock(); + + if( p_._internal_equiv( v ) ) + { + p_.swap( w ); + + l_.unlock(); + return true; + } + else + { + shared_ptr tmp( p_ ); + + l_.unlock(); + + tmp.swap( v ); + return false; + } + } + public: atomic_shared_ptr() BOOST_SP_NOEXCEPT { + boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT; + std::memcpy( &l_, &init, sizeof( init ) ); } - BOOST_CONSTEXPR atomic_shared_ptr( shared_ptr p ) BOOST_SP_NOEXCEPT + atomic_shared_ptr( shared_ptr p ) BOOST_SP_NOEXCEPT #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) : p_( std::move( p ) ) #else : p_( p ) #endif { + boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT; + std::memcpy( &l_, &init, sizeof( init ) ); } atomic_shared_ptr& operator=( shared_ptr r ) BOOST_SP_NOEXCEPT { -#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + boost::detail::spinlock::scoped_lock lock( l_ ); + p_.swap( r ); - atomic_store( &p_, std::move( r ) ); - -#else - - atomic_store( &p_, r ); - -#endif return *this; } @@ -63,80 +89,80 @@ public: shared_ptr load( int = 0 ) const BOOST_SP_NOEXCEPT { - return atomic_load( &p_ ); + boost::detail::spinlock::scoped_lock lock( l_ ); + return p_; } operator shared_ptr() const BOOST_SP_NOEXCEPT { - return atomic_load( &p_ ); + boost::detail::spinlock::scoped_lock lock( l_ ); + return p_; } void store( shared_ptr r, int = 0 ) BOOST_SP_NOEXCEPT { -#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - - atomic_store( &p_, std::move( r ) ); - -#else - - atomic_store( &p_, r ); - -#endif + boost::detail::spinlock::scoped_lock lock( l_ ); + p_.swap( r ); } shared_ptr exchange( shared_ptr r, int = 0 ) BOOST_SP_NOEXCEPT { + { + boost::detail::spinlock::scoped_lock lock( l_ ); + p_.swap( r ); + } + #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - return atomic_exchange( &p_, std::move( r ) ); + return std::move( r ); #else - return atomic_exchange( &p_, r ); + return r; #endif } bool compare_exchange_weak( shared_ptr& v, const shared_ptr& w, int, int ) BOOST_SP_NOEXCEPT { - return atomic_compare_exchange( &p_, &v, w ); + return compare_exchange( v, w ); } bool compare_exchange_weak( shared_ptr& v, const shared_ptr& w, int = 0 ) BOOST_SP_NOEXCEPT { - return atomic_compare_exchange( &p_, &v, w ); + return compare_exchange( v, w ); } bool compare_exchange_strong( shared_ptr& v, const shared_ptr& w, int, int ) BOOST_SP_NOEXCEPT { - return atomic_compare_exchange( &p_, &v, w ); + return compare_exchange( v, w ); } bool compare_exchange_strong( shared_ptr& v, const shared_ptr& w, int = 0 ) BOOST_SP_NOEXCEPT { - return atomic_compare_exchange( &p_, &v, w ); + return compare_exchange( v, w ); } #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) bool compare_exchange_weak( shared_ptr& v, shared_ptr&& w, int, int ) BOOST_SP_NOEXCEPT { - return atomic_compare_exchange( &p_, &v, std::move( w ) ); + return compare_exchange( v, std::move( w ) ); } bool compare_exchange_weak( shared_ptr& v, shared_ptr&& w, int = 0 ) BOOST_SP_NOEXCEPT { - return atomic_compare_exchange( &p_, &v, std::move( w ) ); + return compare_exchange( v, std::move( w ) ); } bool compare_exchange_strong( shared_ptr& v, shared_ptr&& w, int, int ) BOOST_SP_NOEXCEPT { - return atomic_compare_exchange( &p_, &v, std::move( w ) ); + return compare_exchange( v, std::move( w ) ); } bool compare_exchange_strong( shared_ptr& v, shared_ptr&& w, int = 0 ) BOOST_SP_NOEXCEPT { - return atomic_compare_exchange( &p_, &v, std::move( w ) ); + return compare_exchange( v, std::move( w ) ); } #endif