/extlibs/Boost/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp
C++ Header | 131 lines | 86 code | 31 blank | 14 comment | 8 complexity | 8dedcb1ce8856fbf76d35f71c5d64913 MD5 | raw file
1#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED 2#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED 3 4// MS compatible compilers support #pragma once 5 6#if defined(_MSC_VER) && (_MSC_VER >= 1020) 7# pragma once 8#endif 9 10// 11// detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation 12// 13// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 14// Copyright 2004-2008 Peter Dimov 15// 16// Distributed under the Boost Software License, Version 1.0. (See 17// accompanying file LICENSE_1_0.txt or copy at 18// http://www.boost.org/LICENSE_1_0.txt) 19// 20 21#include <boost/detail/sp_typeinfo.hpp> 22#include <boost/smart_ptr/detail/spinlock_pool.hpp> 23 24namespace boost 25{ 26 27namespace detail 28{ 29 30inline int atomic_exchange_and_add( int * pw, int dv ) 31{ 32 spinlock_pool<1>::scoped_lock lock( pw ); 33 34 int r = *pw; 35 *pw += dv; 36 return r; 37} 38 39inline void atomic_increment( int * pw ) 40{ 41 spinlock_pool<1>::scoped_lock lock( pw ); 42 ++*pw; 43} 44 45inline int atomic_conditional_increment( int * pw ) 46{ 47 spinlock_pool<1>::scoped_lock lock( pw ); 48 49 int rv = *pw; 50 if( rv != 0 ) ++*pw; 51 return rv; 52} 53 54class sp_counted_base 55{ 56private: 57 58 sp_counted_base( sp_counted_base const & ); 59 sp_counted_base & operator= ( sp_counted_base const & ); 60 61 int use_count_; // #shared 62 int weak_count_; // #weak + (#shared != 0) 63 64public: 65 66 sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) 67 { 68 } 69 70 virtual ~sp_counted_base() // nothrow 71 { 72 } 73 74 // dispose() is called when use_count_ drops to zero, to release 75 // the resources managed by *this. 76 77 virtual void dispose() = 0; // nothrow 78 79 // destroy() is called when weak_count_ drops to zero. 80 81 virtual void destroy() // nothrow 82 { 83 delete this; 84 } 85 86 virtual void * get_deleter( sp_typeinfo const & ti ) = 0; 87 88 void add_ref_copy() 89 { 90 atomic_increment( &use_count_ ); 91 } 92 93 bool add_ref_lock() // true on success 94 { 95 return atomic_conditional_increment( &use_count_ ) != 0; 96 } 97 98 void release() // nothrow 99 { 100 if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) 101 { 102 dispose(); 103 weak_release(); 104 } 105 } 106 107 void weak_add_ref() // nothrow 108 { 109 atomic_increment( &weak_count_ ); 110 } 111 112 void weak_release() // nothrow 113 { 114 if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 ) 115 { 116 destroy(); 117 } 118 } 119 120 long use_count() const // nothrow 121 { 122 spinlock_pool<1>::scoped_lock lock( &use_count_ ); 123 return use_count_; 124 } 125}; 126 127} // namespace detail 128 129} // namespace boost 130 131#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED