Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:51:42

0001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
0003 
0004 // MS compatible compilers support #pragma once
0005 
0006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0007 # pragma once
0008 #endif
0009 
0010 //
0011 //  detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
0012 //
0013 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
0014 //  Copyright 2004-2008 Peter Dimov
0015 //
0016 //  Distributed under the Boost Software License, Version 1.0. (See
0017 //  accompanying file LICENSE_1_0.txt or copy at
0018 //  http://www.boost.org/LICENSE_1_0.txt)
0019 //
0020 
0021 #include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
0022 #include <boost/smart_ptr/detail/spinlock_pool.hpp>
0023 #include <boost/config.hpp>
0024 
0025 #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
0026 
0027 #include <boost/config/pragma_message.hpp>
0028 BOOST_PRAGMA_MESSAGE("Using spinlock-based sp_counted_base")
0029 
0030 #endif
0031 
0032 namespace boost
0033 {
0034 
0035 namespace detail
0036 {
0037 
0038 inline int atomic_exchange_and_add( int * pw, int dv )
0039 {
0040     spinlock_pool<1>::scoped_lock lock( pw );
0041 
0042     int r = *pw;
0043     *pw += dv;
0044     return r;
0045 }
0046 
0047 inline void atomic_increment( int * pw )
0048 {
0049     spinlock_pool<1>::scoped_lock lock( pw );
0050     ++*pw;
0051 }
0052 
0053 inline int atomic_conditional_increment( int * pw )
0054 {
0055     spinlock_pool<1>::scoped_lock lock( pw );
0056 
0057     int rv = *pw;
0058     if( rv != 0 ) ++*pw;
0059     return rv;
0060 }
0061 
0062 class BOOST_SYMBOL_VISIBLE sp_counted_base
0063 {
0064 private:
0065 
0066     sp_counted_base( sp_counted_base const & );
0067     sp_counted_base & operator= ( sp_counted_base const & );
0068 
0069     int use_count_;        // #shared
0070     int weak_count_;       // #weak + (#shared != 0)
0071 
0072 public:
0073 
0074     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
0075     {
0076     }
0077 
0078     virtual ~sp_counted_base() // nothrow
0079     {
0080     }
0081 
0082     // dispose() is called when use_count_ drops to zero, to release
0083     // the resources managed by *this.
0084 
0085     virtual void dispose() = 0; // nothrow
0086 
0087     // destroy() is called when weak_count_ drops to zero.
0088 
0089     virtual void destroy() // nothrow
0090     {
0091         delete this;
0092     }
0093 
0094     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
0095     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
0096     virtual void * get_untyped_deleter() = 0;
0097 
0098     void add_ref_copy()
0099     {
0100         atomic_increment( &use_count_ );
0101     }
0102 
0103     bool add_ref_lock() // true on success
0104     {
0105         return atomic_conditional_increment( &use_count_ ) != 0;
0106     }
0107 
0108     void release() // nothrow
0109     {
0110         if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
0111         {
0112             dispose();
0113             weak_release();
0114         }
0115     }
0116 
0117     void weak_add_ref() // nothrow
0118     {
0119         atomic_increment( &weak_count_ );
0120     }
0121 
0122     void weak_release() // nothrow
0123     {
0124         if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
0125         {
0126             destroy();
0127         }
0128     }
0129 
0130     long use_count() const // nothrow
0131     {
0132         spinlock_pool<1>::scoped_lock lock( &use_count_ );
0133         return use_count_;
0134     }
0135 };
0136 
0137 } // namespace detail
0138 
0139 } // namespace boost
0140 
0141 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED