sp_counted_base_spin.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
00003 
00004 // MS compatible compilers support #pragma once
00005 
00006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
00007 # pragma once
00008 #endif
00009 
00010 //
00011 //  detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
00012 //
00013 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
00014 //  Copyright 2004-2008 Peter Dimov
00015 //
00016 //  Distributed under the Boost Software License, Version 1.0. (See
00017 //  accompanying file LICENSE_1_0.txt or copy at
00018 //  http://www.boost.org/LICENSE_1_0.txt)
00019 //
00020 
00021 #include <boost/detail/sp_typeinfo.hpp>
00022 #include <boost/smart_ptr/detail/spinlock_pool.hpp>
00023 
00024 namespace boost
00025 {
00026 
00027 namespace detail
00028 {
00029 
00030 inline int atomic_exchange_and_add( int * pw, int dv )
00031 {
00032     spinlock_pool<1>::scoped_lock lock( pw );
00033 
00034     int r = *pw;
00035     *pw += dv;
00036     return r;
00037 }
00038 
00039 inline void atomic_increment( int * pw )
00040 {
00041     spinlock_pool<1>::scoped_lock lock( pw );
00042     ++*pw;
00043 }
00044 
00045 inline int atomic_conditional_increment( int * pw )
00046 {
00047     spinlock_pool<1>::scoped_lock lock( pw );
00048 
00049     int rv = *pw;
00050     if( rv != 0 ) ++*pw;
00051     return rv;
00052 }
00053 
00054 class sp_counted_base
00055 {
00056 private:
00057 
00058     sp_counted_base( sp_counted_base const & );
00059     sp_counted_base & operator= ( sp_counted_base const & );
00060 
00061     int use_count_;        // #shared
00062     int weak_count_;       // #weak + (#shared != 0)
00063 
00064 public:
00065 
00066     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00067     {
00068     }
00069 
00070     virtual ~sp_counted_base() // nothrow
00071     {
00072     }
00073 
00074     // dispose() is called when use_count_ drops to zero, to release
00075     // the resources managed by *this.
00076 
00077     virtual void dispose() = 0; // nothrow
00078 
00079     // destroy() is called when weak_count_ drops to zero.
00080 
00081     virtual void destroy() // nothrow
00082     {
00083         delete this;
00084     }
00085 
00086     virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00087 
00088     void add_ref_copy()
00089     {
00090         atomic_increment( &use_count_ );
00091     }
00092 
00093     bool add_ref_lock() // true on success
00094     {
00095         return atomic_conditional_increment( &use_count_ ) != 0;
00096     }
00097 
00098     void release() // nothrow
00099     {
00100         if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
00101         {
00102             dispose();
00103             weak_release();
00104         }
00105     }
00106 
00107     void weak_add_ref() // nothrow
00108     {
00109         atomic_increment( &weak_count_ );
00110     }
00111 
00112     void weak_release() // nothrow
00113     {
00114         if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
00115         {
00116             destroy();
00117         }
00118     }
00119 
00120     long use_count() const // nothrow
00121     {
00122         spinlock_pool<1>::scoped_lock lock( &use_count_ );
00123         return use_count_;
00124     }
00125 };
00126 
00127 } // namespace detail
00128 
00129 } // namespace boost
00130 
00131 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29