• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
2 #define BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
3 
4 //
5 //  atomic_shared_ptr.hpp
6 //
7 //  Copyright 2017 Peter Dimov
8 //
9 //  Distributed under the Boost Software License, Version 1.0. (See
10 //  accompanying file LICENSE_1_0.txt or copy at
11 //  http://www.boost.org/LICENSE_1_0.txt)
12 //
13 //  See http://www.boost.org/libs/smart_ptr/ for documentation.
14 //
15 
16 #include <boost/smart_ptr/shared_ptr.hpp>
17 #include <boost/smart_ptr/detail/spinlock.hpp>
18 #include <cstring>
19 
20 namespace boost
21 {
22 
23 template<class T> class atomic_shared_ptr
24 {
25 private:
26 
27     boost::shared_ptr<T> p_;
28 
29     mutable boost::detail::spinlock l_;
30 
31     atomic_shared_ptr(const atomic_shared_ptr&);
32     atomic_shared_ptr& operator=(const atomic_shared_ptr&);
33 
34 private:
35 
compare_exchange(shared_ptr<T> & v,shared_ptr<T> w)36     bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
37     {
38         l_.lock();
39 
40         if( p_._internal_equiv( v ) )
41         {
42             p_.swap( w );
43 
44             l_.unlock();
45             return true;
46         }
47         else
48         {
49             shared_ptr<T> tmp( p_ );
50 
51             l_.unlock();
52 
53             tmp.swap( v );
54             return false;
55         }
56     }
57 
58 public:
59 
60 #if !defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX ) && !defined( BOOST_NO_CXX11_CONSTEXPR )
61 
atomic_shared_ptr()62     constexpr atomic_shared_ptr() BOOST_SP_NOEXCEPT: l_ BOOST_DETAIL_SPINLOCK_INIT
63     {
64     }
65 
atomic_shared_ptr(shared_ptr<T> p)66     atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
67         : p_( std::move( p ) ), l_ BOOST_DETAIL_SPINLOCK_INIT
68     {
69     }
70 
71 #else
72 
73     atomic_shared_ptr() BOOST_SP_NOEXCEPT
74     {
75         boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
76         std::memcpy( &l_, &init, sizeof( init ) );
77     }
78 
79     atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
80 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
81         : p_( std::move( p ) )
82 #else
83         : p_( p )
84 #endif
85     {
86         boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
87         std::memcpy( &l_, &init, sizeof( init ) );
88     }
89 
90 #endif
91 
operator =(shared_ptr<T> r)92     atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
93     {
94         boost::detail::spinlock::scoped_lock lock( l_ );
95         p_.swap( r );
96 
97         return *this;
98     }
99 
is_lock_free() const100     BOOST_CONSTEXPR bool is_lock_free() const BOOST_SP_NOEXCEPT
101     {
102         return false;
103     }
104 
load() const105     shared_ptr<T> load() const BOOST_SP_NOEXCEPT
106     {
107         boost::detail::spinlock::scoped_lock lock( l_ );
108         return p_;
109     }
110 
load(M) const111     template<class M> shared_ptr<T> load( M ) const BOOST_SP_NOEXCEPT
112     {
113         boost::detail::spinlock::scoped_lock lock( l_ );
114         return p_;
115     }
116 
operator shared_ptr<T>() const117     operator shared_ptr<T>() const BOOST_SP_NOEXCEPT
118     {
119         boost::detail::spinlock::scoped_lock lock( l_ );
120         return p_;
121     }
122 
store(shared_ptr<T> r)123     void store( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
124     {
125         boost::detail::spinlock::scoped_lock lock( l_ );
126         p_.swap( r );
127     }
128 
store(shared_ptr<T> r,M)129     template<class M> void store( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
130     {
131         boost::detail::spinlock::scoped_lock lock( l_ );
132         p_.swap( r );
133     }
134 
exchange(shared_ptr<T> r)135     shared_ptr<T> exchange( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
136     {
137         {
138             boost::detail::spinlock::scoped_lock lock( l_ );
139             p_.swap( r );
140         }
141 
142 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
143 
144         return std::move( r );
145 
146 #else
147 
148         return r;
149 
150 #endif
151     }
152 
exchange(shared_ptr<T> r,M)153     template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
154     {
155         {
156             boost::detail::spinlock::scoped_lock lock( l_ );
157             p_.swap( r );
158         }
159 
160 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
161 
162         return std::move( r );
163 
164 #else
165 
166         return r;
167 
168 #endif
169     }
170 
compare_exchange_weak(shared_ptr<T> & v,const shared_ptr<T> & w,M,M)171     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT
172     {
173         return compare_exchange( v, w );
174     }
175 
compare_exchange_weak(shared_ptr<T> & v,const shared_ptr<T> & w,M)176     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT
177     {
178         return compare_exchange( v, w );
179     }
180 
compare_exchange_weak(shared_ptr<T> & v,const shared_ptr<T> & w)181     bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT
182     {
183         return compare_exchange( v, w );
184     }
185 
compare_exchange_strong(shared_ptr<T> & v,const shared_ptr<T> & w,M,M)186     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT
187     {
188         return compare_exchange( v, w );
189     }
190 
compare_exchange_strong(shared_ptr<T> & v,const shared_ptr<T> & w,M)191     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT
192     {
193         return compare_exchange( v, w );
194     }
195 
compare_exchange_strong(shared_ptr<T> & v,const shared_ptr<T> & w)196     bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT
197     {
198         return compare_exchange( v, w );
199     }
200 
201 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
202 
compare_exchange_weak(shared_ptr<T> & v,shared_ptr<T> && w,M,M)203     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT
204     {
205         return compare_exchange( v, std::move( w ) );
206     }
207 
compare_exchange_weak(shared_ptr<T> & v,shared_ptr<T> && w,M)208     template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT
209     {
210         return compare_exchange( v, std::move( w ) );
211     }
212 
compare_exchange_weak(shared_ptr<T> & v,shared_ptr<T> && w)213     bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
214     {
215         return compare_exchange( v, std::move( w ) );
216     }
217 
compare_exchange_strong(shared_ptr<T> & v,shared_ptr<T> && w,M,M)218     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT
219     {
220         return compare_exchange( v, std::move( w ) );
221     }
222 
compare_exchange_strong(shared_ptr<T> & v,shared_ptr<T> && w,M)223     template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT
224     {
225         return compare_exchange( v, std::move( w ) );
226     }
227 
compare_exchange_strong(shared_ptr<T> & v,shared_ptr<T> && w)228     bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
229     {
230         return compare_exchange( v, std::move( w ) );
231     }
232 
233 #endif
234 };
235 
236 } // namespace boost
237 
238 #endif  // #ifndef BOOST_SMART_PTR_ATOMIC_SHARED_PTR_HPP_INCLUDED
239