• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
2 #define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
3 
4 #ifndef BOOST_CONFIG_HPP
5 #  include <boost/config.hpp>
6 #endif
7 #
8 #if defined(BOOST_HAS_PRAGMA_ONCE)
9 # pragma once
10 #endif
11 
12 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
13 //  Copyright 2004-2005 Peter Dimov
14 //  Copyright 2007-2012 Ion Gaztanaga
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 //  Lock-free algorithm by Alexander Terekhov
22 //
23 //  Thanks to Ben Hitchings for the #weak + (#shared != 0)
24 //  formulation
25 //
26 
27 #include <boost/interprocess/detail/config_begin.hpp>
28 #include <boost/interprocess/detail/workaround.hpp>
29 
30 #include <boost/interprocess/detail/atomic.hpp>
31 #include <typeinfo>
32 
33 namespace boost {
34 
35 namespace interprocess {
36 
37 namespace ipcdetail {
38 
39 class sp_counted_base
40 {
41 private:
42 
43     sp_counted_base( sp_counted_base const & );
44     sp_counted_base & operator= ( sp_counted_base const & );
45 
46     boost::uint32_t use_count_;        // #shared
47     boost::uint32_t weak_count_;       // #weak + (#shared != 0)
48 
49 public:
50 
sp_counted_base()51     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
52     {}
53 
~sp_counted_base()54     ~sp_counted_base() // nothrow
55     {}
56 
add_ref_copy()57     void add_ref_copy()
58     {
59         ipcdetail::atomic_inc32( &use_count_ );
60     }
61 
add_ref_lock()62     bool add_ref_lock() // true on success
63     {
64         for( ;; )
65         {
66             boost::uint32_t tmp = static_cast< boost::uint32_t const volatile& >( use_count_ );
67             if( tmp == 0 ) return false;
68             if( ipcdetail::atomic_cas32( &use_count_, tmp + 1, tmp ) == tmp )
69                return true;
70         }
71     }
72 
ref_release()73    bool ref_release() // nothrow
74    { return 1 == ipcdetail::atomic_dec32( &use_count_ );  }
75 
weak_add_ref()76    void weak_add_ref() // nothrow
77    { ipcdetail::atomic_inc32( &weak_count_ ); }
78 
weak_release()79    bool weak_release() // nothrow
80    { return 1 == ipcdetail::atomic_dec32( &weak_count_ ); }
81 
use_count() const82    long use_count() const // nothrow
83    { return (long)static_cast<boost::uint32_t const volatile &>( use_count_ ); }
84 };
85 
86 } // namespace ipcdetail
87 
88 } // namespace interprocess
89 
90 } // namespace boost
91 
92 #include <boost/interprocess/detail/config_end.hpp>
93 
94 #endif  // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
95