sp_counted_base_atomic.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
  2. #define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
  3. #ifndef BOOST_CONFIG_HPP
  4. # include <boost/config.hpp>
  5. #endif
  6. #
  7. #if defined(BOOST_HAS_PRAGMA_ONCE)
  8. # pragma once
  9. #endif
  10. // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
  11. // Copyright 2004-2005 Peter Dimov
  12. // Copyright 2007-2012 Ion Gaztanaga
  13. //
  14. // Distributed under the Boost Software License, Version 1.0. (See
  15. // accompanying file LICENSE_1_0.txt or copy at
  16. // http://www.boost.org/LICENSE_1_0.txt)
  17. //
  18. //
  19. // Lock-free algorithm by Alexander Terekhov
  20. //
  21. // Thanks to Ben Hitchings for the #weak + (#shared != 0)
  22. // formulation
  23. //
  24. #include <boost/interprocess/detail/config_begin.hpp>
  25. #include <boost/interprocess/detail/workaround.hpp>
  26. #include <boost/interprocess/detail/atomic.hpp>
  27. #include <typeinfo>
  28. namespace boost {
  29. namespace interprocess {
  30. namespace ipcdetail {
  31. class sp_counted_base
  32. {
  33. private:
  34. sp_counted_base( sp_counted_base const & );
  35. sp_counted_base & operator= ( sp_counted_base const & );
  36. boost::uint32_t use_count_; // #shared
  37. boost::uint32_t weak_count_; // #weak + (#shared != 0)
  38. public:
  39. sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
  40. {}
  41. ~sp_counted_base() // nothrow
  42. {}
  43. void add_ref_copy()
  44. {
  45. ipcdetail::atomic_inc32( &use_count_ );
  46. }
  47. bool add_ref_lock() // true on success
  48. {
  49. for( ;; )
  50. {
  51. boost::uint32_t tmp = static_cast< boost::uint32_t const volatile& >( use_count_ );
  52. if( tmp == 0 ) return false;
  53. if( ipcdetail::atomic_cas32( &use_count_, tmp + 1, tmp ) == tmp )
  54. return true;
  55. }
  56. }
  57. bool ref_release() // nothrow
  58. { return 1 == ipcdetail::atomic_dec32( &use_count_ ); }
  59. void weak_add_ref() // nothrow
  60. { ipcdetail::atomic_inc32( &weak_count_ ); }
  61. bool weak_release() // nothrow
  62. { return 1 == ipcdetail::atomic_dec32( &weak_count_ ); }
  63. long use_count() const // nothrow
  64. { return (long)static_cast<boost::uint32_t const volatile &>( use_count_ ); }
  65. };
  66. } // namespace ipcdetail
  67. } // namespace interprocess
  68. } // namespace boost
  69. #include <boost/interprocess/detail/config_end.hpp>
  70. #endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED