| #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED |
| #define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED |
| |
| // MS compatible compilers support #pragma once |
| |
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| # pragma once |
| #endif |
| |
| // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. |
| // Copyright 2004-2005 Peter Dimov |
| // Copyright 2007-2009 Ion Gaztanaga |
| // |
| // Distributed under the Boost Software License, Version 1.0. (See |
| // accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| // |
| // |
| // Lock-free algorithm by Alexander Terekhov |
| // |
| // Thanks to Ben Hitchings for the #weak + (#shared != 0) |
| // formulation |
| // |
| |
| #include <boost/interprocess/detail/config_begin.hpp> |
| #include <boost/interprocess/detail/workaround.hpp> |
| |
| #include <boost/interprocess/detail/atomic.hpp> |
| #include <typeinfo> |
| |
| namespace boost { |
| |
| namespace interprocess { |
| |
| namespace detail { |
| |
| class sp_counted_base |
| { |
| private: |
| |
| sp_counted_base( sp_counted_base const & ); |
| sp_counted_base & operator= ( sp_counted_base const & ); |
| |
| boost::uint32_t use_count_; // #shared |
| boost::uint32_t weak_count_; // #weak + (#shared != 0) |
| |
| public: |
| |
| sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) |
| {} |
| |
| ~sp_counted_base() // nothrow |
| {} |
| |
| void add_ref_copy() |
| { |
| detail::atomic_inc32( &use_count_ ); |
| } |
| |
| bool add_ref_lock() // true on success |
| { |
| for( ;; ) |
| { |
| boost::uint32_t tmp = static_cast< boost::uint32_t const volatile& >( use_count_ ); |
| if( tmp == 0 ) return false; |
| if( detail::atomic_cas32( &use_count_, tmp + 1, tmp ) == tmp ) |
| return true; |
| } |
| } |
| |
| bool ref_release() // nothrow |
| { return 1 == detail::atomic_dec32( &use_count_ ); } |
| |
| void weak_add_ref() // nothrow |
| { detail::atomic_inc32( &weak_count_ ); } |
| |
| bool weak_release() // nothrow |
| { return 1 == detail::atomic_dec32( &weak_count_ ); } |
| |
| long use_count() const // nothrow |
| { return (long)static_cast<boost::uint32_t const volatile &>( use_count_ ); } |
| }; |
| |
| } // namespace detail |
| |
| } // namespace interprocess |
| |
| } // namespace boost |
| |
| #include <boost/interprocess/detail/config_end.hpp> |
| |
| #endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED |