00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED 00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED 00003 00004 // 00005 // detail/sp_counted_base_solaris.hpp 00006 // based on: detail/sp_counted_base_w32.hpp 00007 // 00008 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 00009 // Copyright 2004-2005 Peter Dimov 00010 // Copyright 2006 Michael van der Westhuizen 00011 // 00012 // Distributed under the Boost Software License, Version 1.0. (See 00013 // accompanying file LICENSE_1_0.txt or copy at 00014 // http://www.boost.org/LICENSE_1_0.txt) 00015 // 00016 // 00017 // Lock-free algorithm by Alexander Terekhov 00018 // 00019 // Thanks to Ben Hitchings for the #weak + (#shared != 0) 00020 // formulation 00021 // 00022 00023 #include <boost/detail/sp_typeinfo.hpp> 00024 #include <atomic.h> 00025 00026 namespace boost 00027 { 00028 00029 namespace detail 00030 { 00031 00032 class sp_counted_base 00033 { 00034 private: 00035 00036 sp_counted_base( sp_counted_base const & ); 00037 sp_counted_base & operator= ( sp_counted_base const & ); 00038 00039 uint32_t use_count_; // #shared 00040 uint32_t weak_count_; // #weak + (#shared != 0) 00041 00042 public: 00043 00044 sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) 00045 { 00046 } 00047 00048 virtual ~sp_counted_base() // nothrow 00049 { 00050 } 00051 00052 // dispose() is called when use_count_ drops to zero, to release 00053 // the resources managed by *this. 00054 00055 virtual void dispose() = 0; // nothrow 00056 00057 // destroy() is called when weak_count_ drops to zero. 00058 00059 virtual void destroy() // nothrow 00060 { 00061 delete this; 00062 } 00063 00064 virtual void * get_deleter( sp_typeinfo const & ti ) = 0; 00065 00066 void add_ref_copy() 00067 { 00068 atomic_inc_32( &use_count_ ); 00069 } 00070 00071 bool add_ref_lock() // true on success 00072 { 00073 for( ;; ) 00074 { 00075 uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ ); 00076 if( tmp == 0 ) return false; 00077 if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true; 00078 } 00079 } 00080 00081 void release() // nothrow 00082 { 00083 if( atomic_dec_32_nv( &use_count_ ) == 0 ) 00084 { 00085 dispose(); 00086 weak_release(); 00087 } 00088 } 00089 00090 void weak_add_ref() // nothrow 00091 { 00092 atomic_inc_32( &weak_count_ ); 00093 } 00094 00095 void weak_release() // nothrow 00096 { 00097 if( atomic_dec_32_nv( &weak_count_ ) == 0 ) 00098 { 00099 destroy(); 00100 } 00101 } 00102 00103 long use_count() const // nothrow 00104 { 00105 return static_cast<long const volatile &>( use_count_ ); 00106 } 00107 }; 00108 00109 } // namespace detail 00110 00111 } // namespace boost 00112 00113 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED