forked from boostorg/smart_ptr
Add a spinlock to atomic_shared_ptr
This commit is contained in:
@@ -36,7 +36,7 @@ namespace boost {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
atomic_shared_ptr() noexcept = default;
|
atomic_shared_ptr() noexcept = default;
|
||||||
constexpr atomic_shared_ptr( shared_ptr<T> p ) noexcept;
|
atomic_shared_ptr( shared_ptr<T> p ) noexcept;
|
||||||
|
|
||||||
atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept;
|
atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept;
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ namespace boost {
|
|||||||
## Members
|
## Members
|
||||||
|
|
||||||
```
|
```
|
||||||
constexpr atomic_shared_ptr( shared_ptr<T> p ) noexcept;
|
atomic_shared_ptr( shared_ptr<T> p ) noexcept;
|
||||||
```
|
```
|
||||||
[none]
|
[none]
|
||||||
* {blank}
|
* {blank}
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/spinlock.hpp>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -24,35 +26,59 @@ private:
|
|||||||
|
|
||||||
boost::shared_ptr<T> p_;
|
boost::shared_ptr<T> p_;
|
||||||
|
|
||||||
|
mutable boost::detail::spinlock l_;
|
||||||
|
|
||||||
atomic_shared_ptr(const atomic_shared_ptr&);
|
atomic_shared_ptr(const atomic_shared_ptr&);
|
||||||
atomic_shared_ptr& operator=(const atomic_shared_ptr&);
|
atomic_shared_ptr& operator=(const atomic_shared_ptr&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
l_.lock();
|
||||||
|
|
||||||
|
if( p_._internal_equiv( v ) )
|
||||||
|
{
|
||||||
|
p_.swap( w );
|
||||||
|
|
||||||
|
l_.unlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shared_ptr<T> tmp( p_ );
|
||||||
|
|
||||||
|
l_.unlock();
|
||||||
|
|
||||||
|
tmp.swap( v );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
atomic_shared_ptr() BOOST_SP_NOEXCEPT
|
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<T> p ) BOOST_SP_NOEXCEPT
|
atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
|
||||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
: p_( std::move( p ) )
|
: p_( std::move( p ) )
|
||||||
#else
|
#else
|
||||||
: p_( p )
|
: p_( p )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
|
||||||
|
std::memcpy( &l_, &init, sizeof( init ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
|
atomic_shared_ptr& operator=( shared_ptr<T> 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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,80 +89,80 @@ public:
|
|||||||
|
|
||||||
shared_ptr<T> load( int = 0 ) const BOOST_SP_NOEXCEPT
|
shared_ptr<T> load( int = 0 ) const BOOST_SP_NOEXCEPT
|
||||||
{
|
{
|
||||||
return atomic_load( &p_ );
|
boost::detail::spinlock::scoped_lock lock( l_ );
|
||||||
|
return p_;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator shared_ptr<T>() const BOOST_SP_NOEXCEPT
|
operator shared_ptr<T>() const BOOST_SP_NOEXCEPT
|
||||||
{
|
{
|
||||||
return atomic_load( &p_ );
|
boost::detail::spinlock::scoped_lock lock( l_ );
|
||||||
|
return p_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void store( shared_ptr<T> r, int = 0 ) BOOST_SP_NOEXCEPT
|
void store( shared_ptr<T> r, int = 0 ) 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) BOOST_SP_NOEXCEPT
|
shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) BOOST_SP_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
boost::detail::spinlock::scoped_lock lock( l_ );
|
||||||
|
p_.swap( r );
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
return atomic_exchange( &p_, std::move( r ) );
|
return std::move( r );
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
return atomic_exchange( &p_, r );
|
return r;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) BOOST_SP_NOEXCEPT
|
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) BOOST_SP_NOEXCEPT
|
||||||
{
|
{
|
||||||
return atomic_compare_exchange( &p_, &v, w );
|
return compare_exchange( v, w );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) BOOST_SP_NOEXCEPT
|
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) BOOST_SP_NOEXCEPT
|
||||||
{
|
{
|
||||||
return atomic_compare_exchange( &p_, &v, w );
|
return compare_exchange( v, w );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) BOOST_SP_NOEXCEPT
|
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) BOOST_SP_NOEXCEPT
|
||||||
{
|
{
|
||||||
return atomic_compare_exchange( &p_, &v, w );
|
return compare_exchange( v, w );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) BOOST_SP_NOEXCEPT
|
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& 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 )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) BOOST_SP_NOEXCEPT
|
bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& 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<T>& v, shared_ptr<T>&& w, int = 0 ) BOOST_SP_NOEXCEPT
|
bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& 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<T>& v, shared_ptr<T>&& w, int, int ) BOOST_SP_NOEXCEPT
|
bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& 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<T>& v, shared_ptr<T>&& w, int = 0 ) BOOST_SP_NOEXCEPT
|
bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) BOOST_SP_NOEXCEPT
|
||||||
{
|
{
|
||||||
return atomic_compare_exchange( &p_, &v, std::move( w ) );
|
return compare_exchange( v, std::move( w ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user