File indexing completed on 2025-01-18 09:51:43
0001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
0003
0004
0005
0006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0007 # pragma once
0008 #endif
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
0019 #include <boost/config.hpp>
0020 #include <limits.h>
0021
0022 #if defined( __ia64__ ) && defined( __INTEL_COMPILER )
0023 # include <ia64intrin.h>
0024 #endif
0025
0026 #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
0027
0028 #include <boost/config/pragma_message.hpp>
0029 BOOST_PRAGMA_MESSAGE("Using __sync sp_counted_base")
0030
0031 #endif
0032
0033 namespace boost
0034 {
0035
0036 namespace detail
0037 {
0038
0039 #if INT_MAX >= 2147483647
0040
0041 typedef int sp_int32_t;
0042
0043 #else
0044
0045 typedef long sp_int32_t;
0046
0047 #endif
0048
0049 inline void atomic_increment( sp_int32_t * pw )
0050 {
0051 __sync_fetch_and_add( pw, 1 );
0052 }
0053
0054 inline sp_int32_t atomic_decrement( sp_int32_t * pw )
0055 {
0056 return __sync_fetch_and_add( pw, -1 );
0057 }
0058
0059 inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
0060 {
0061
0062
0063
0064
0065 sp_int32_t r = *pw;
0066
0067 for( ;; )
0068 {
0069 if( r == 0 )
0070 {
0071 return r;
0072 }
0073
0074 sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
0075
0076 if( r2 == r )
0077 {
0078 return r;
0079 }
0080 else
0081 {
0082 r = r2;
0083 }
0084 }
0085 }
0086
0087 class BOOST_SYMBOL_VISIBLE sp_counted_base
0088 {
0089 private:
0090
0091 sp_counted_base( sp_counted_base const & );
0092 sp_counted_base & operator= ( sp_counted_base const & );
0093
0094 sp_int32_t use_count_;
0095 sp_int32_t weak_count_;
0096
0097 public:
0098
0099 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
0100 {
0101 }
0102
0103 virtual ~sp_counted_base()
0104 {
0105 }
0106
0107
0108
0109
0110 virtual void dispose() = 0;
0111
0112
0113
0114 virtual void destroy()
0115 {
0116 delete this;
0117 }
0118
0119 virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
0120 virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
0121 virtual void * get_untyped_deleter() = 0;
0122
0123 void add_ref_copy()
0124 {
0125 atomic_increment( &use_count_ );
0126 }
0127
0128 bool add_ref_lock()
0129 {
0130 return atomic_conditional_increment( &use_count_ ) != 0;
0131 }
0132
0133 void release()
0134 {
0135 if( atomic_decrement( &use_count_ ) == 1 )
0136 {
0137 dispose();
0138 weak_release();
0139 }
0140 }
0141
0142 void weak_add_ref()
0143 {
0144 atomic_increment( &weak_count_ );
0145 }
0146
0147 void weak_release()
0148 {
0149 if( atomic_decrement( &weak_count_ ) == 1 )
0150 {
0151 destroy();
0152 }
0153 }
0154
0155 long use_count() const
0156 {
0157 return const_cast< sp_int32_t const volatile & >( use_count_ );
0158 }
0159 };
0160
0161 }
0162
0163 }
0164
0165 #endif