#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 |