fixing stuff
[dyninst.git] / dynutil / h / dyn_detail / boost / detail / sp_counted_base_solaris.hpp
1 #ifndef DYN_DETAIL_BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
2 #define DYN_DETAIL_BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
3
4 //
5 //  detail/sp_counted_base_solaris.hpp
6 //   based on: detail/sp_counted_base_w32.hpp
7 //
8 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
9 //  Copyright 2004-2005 Peter Dimov
10 //  Copyright 2006 Michael van der Westhuizen
11 //
12 //  Distributed under the Boost Software License, Version 1.0. (See
13 //  accompanying file LICENSE_1_0.txt or copy at
14 //  http://www.boost.org/LICENSE_1_0.txt)
15 //
16 //
17 //  Lock-free algorithm by Alexander Terekhov
18 //
19 //  Thanks to Ben Hitchings for the #weak + (#shared != 0)
20 //  formulation
21 //
22
23 #include <dyn_detail/boost/detail/sp_typeinfo.hpp>
24 #include <atomic.h>
25
26 namespace dyn_detail
27 {
28   
29 namespace boost
30 {
31
32 namespace detail
33 {
34
35 class sp_counted_base
36 {
37 private:
38
39     sp_counted_base( sp_counted_base const & );
40     sp_counted_base & operator= ( sp_counted_base const & );
41
42     uint32_t use_count_;        // #shared
43     uint32_t weak_count_;       // #weak + (#shared != 0)
44
45 public:
46
47     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
48     {
49     }
50
51     virtual ~sp_counted_base() // nothrow
52     {
53     }
54
55     // dispose() is called when use_count_ drops to zero, to release
56     // the resources managed by *this.
57
58     virtual void dispose() = 0; // nothrow
59
60     // destroy() is called when weak_count_ drops to zero.
61
62     virtual void destroy() // nothrow
63     {
64         delete this;
65     }
66
67     virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
68
69     void add_ref_copy()
70     {
71         atomic_inc_32( &use_count_ );
72     }
73
74     bool add_ref_lock() // true on success
75     {
76         for( ;; )
77         {
78             uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ );
79             if( tmp == 0 ) return false;
80             if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true;
81         }
82     }
83
84     void release() // nothrow
85     {
86         if( atomic_dec_32_nv( &use_count_ ) == 0 )
87         {
88             dispose();
89             weak_release();
90         }
91     }
92
93     void weak_add_ref() // nothrow
94     {
95         atomic_inc_32( &weak_count_ );
96     }
97
98     void weak_release() // nothrow
99     {
100         if( atomic_dec_32_nv( &weak_count_ ) == 0 )
101         {
102             destroy();
103         }
104     }
105
106     long use_count() const // nothrow
107     {
108         return static_cast<long const volatile &>( use_count_ );
109     }
110 };
111
112 } // namespace detail
113
114 } // namespace boost
115  
116 } // namespace dyn_detail
117
118 #endif  // #ifndef DYN_DETAIL_BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED