]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/smart_ptr/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / smart_ptr / include / boost / smart_ptr / detail / sp_counted_base_spin.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
3
4 // MS compatible compilers support #pragma once
5
6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7 # pragma once
8 #endif
9
10 //
11 // detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
12 //
13 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
14 // Copyright 2004-2008 Peter Dimov
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 #include <boost/detail/sp_typeinfo.hpp>
22 #include <boost/smart_ptr/detail/spinlock_pool.hpp>
23
24 namespace boost
25 {
26
27 namespace detail
28 {
29
30 inline int atomic_exchange_and_add( int * pw, int dv )
31 {
32 spinlock_pool<1>::scoped_lock lock( pw );
33
34 int r = *pw;
35 *pw += dv;
36 return r;
37 }
38
39 inline void atomic_increment( int * pw )
40 {
41 spinlock_pool<1>::scoped_lock lock( pw );
42 ++*pw;
43 }
44
45 inline int atomic_conditional_increment( int * pw )
46 {
47 spinlock_pool<1>::scoped_lock lock( pw );
48
49 int rv = *pw;
50 if( rv != 0 ) ++*pw;
51 return rv;
52 }
53
54 class sp_counted_base
55 {
56 private:
57
58 sp_counted_base( sp_counted_base const & );
59 sp_counted_base & operator= ( sp_counted_base const & );
60
61 int use_count_; // #shared
62 int weak_count_; // #weak + (#shared != 0)
63
64 public:
65
66 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
67 {
68 }
69
70 virtual ~sp_counted_base() // nothrow
71 {
72 }
73
74 // dispose() is called when use_count_ drops to zero, to release
75 // the resources managed by *this.
76
77 virtual void dispose() = 0; // nothrow
78
79 // destroy() is called when weak_count_ drops to zero.
80
81 virtual void destroy() // nothrow
82 {
83 delete this;
84 }
85
86 virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
87 virtual void * get_untyped_deleter() = 0;
88
89 void add_ref_copy()
90 {
91 atomic_increment( &use_count_ );
92 }
93
94 bool add_ref_lock() // true on success
95 {
96 return atomic_conditional_increment( &use_count_ ) != 0;
97 }
98
99 void release() // nothrow
100 {
101 if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
102 {
103 dispose();
104 weak_release();
105 }
106 }
107
108 void weak_add_ref() // nothrow
109 {
110 atomic_increment( &weak_count_ );
111 }
112
113 void weak_release() // nothrow
114 {
115 if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
116 {
117 destroy();
118 }
119 }
120
121 long use_count() const // nothrow
122 {
123 spinlock_pool<1>::scoped_lock lock( &use_count_ );
124 return use_count_;
125 }
126 };
127
128 } // namespace detail
129
130 } // namespace boost
131
132 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED