doc_intrusive.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/interprocess for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #include <boost/interprocess/detail/config_begin.hpp>
  11. #include <boost/interprocess/detail/workaround.hpp>
  12. //[doc_intrusive
  13. #include <boost/interprocess/managed_shared_memory.hpp>
  14. #include <boost/interprocess/smart_ptr/intrusive_ptr.hpp>
  15. //<-
  16. #include "../test/get_process_id_name.hpp"
  17. //->
  18. using namespace boost::interprocess;
  19. namespace N {
  20. //A class that has an internal reference count
  21. class reference_counted_class
  22. {
  23. private:
  24. //Non-copyable
  25. reference_counted_class(const reference_counted_class &);
  26. //Non-assignable
  27. reference_counted_class & operator=(const reference_counted_class &);
  28. //A typedef to save typing
  29. typedef managed_shared_memory::segment_manager segment_manager;
  30. //This is the reference count
  31. unsigned int m_use_count;
  32. //The segment manager allows deletion from shared memory segment
  33. offset_ptr<segment_manager> mp_segment_manager;
  34. public:
  35. //Constructor
  36. reference_counted_class(segment_manager *s_mngr)
  37. : m_use_count(0), mp_segment_manager(s_mngr){}
  38. //Destructor
  39. ~reference_counted_class(){}
  40. public:
  41. //Returns the reference count
  42. unsigned int use_count() const
  43. { return m_use_count; }
  44. //Adds a reference
  45. inline friend void intrusive_ptr_add_ref(reference_counted_class * p)
  46. { ++p->m_use_count; }
  47. //Releases a reference
  48. inline friend void intrusive_ptr_release(reference_counted_class * p)
  49. { if(--p->m_use_count == 0) p->mp_segment_manager->destroy_ptr(p); }
  50. };
  51. } //namespace N {
  52. //A class that has an intrusive pointer to reference_counted_class
  53. class intrusive_ptr_owner
  54. {
  55. typedef intrusive_ptr<N::reference_counted_class,
  56. offset_ptr<void> > intrusive_ptr_t;
  57. intrusive_ptr_t m_intrusive_ptr;
  58. public:
  59. //Takes a pointer to the reference counted class
  60. intrusive_ptr_owner(N::reference_counted_class *ptr)
  61. : m_intrusive_ptr(ptr){}
  62. };
  63. int main()
  64. {
  65. //Remove shared memory on construction and destruction
  66. struct shm_remove
  67. {
  68. //<-
  69. #if 1
  70. shm_remove() { shared_memory_object::remove(test::get_process_id_name()); }
  71. ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); }
  72. #else
  73. //->
  74. shm_remove() { shared_memory_object::remove("MySharedMemory"); }
  75. ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
  76. //<-
  77. #endif
  78. //->
  79. } remover;
  80. //<-
  81. (void)remover;
  82. //->
  83. //Create shared memory
  84. //<-
  85. #if 1
  86. managed_shared_memory shmem(create_only, test::get_process_id_name(), 10000);
  87. #else
  88. //->
  89. managed_shared_memory shmem(create_only, "MySharedMemory", 10000);
  90. //<-
  91. #endif
  92. //->
  93. //Create the unique reference counted object in shared memory
  94. N::reference_counted_class *ref_counted =
  95. shmem.construct<N::reference_counted_class>
  96. ("ref_counted")(shmem.get_segment_manager());
  97. //Create an array of ten intrusive pointer owners in shared memory
  98. intrusive_ptr_owner *intrusive_owner_array =
  99. shmem.construct<intrusive_ptr_owner>
  100. (anonymous_instance)[10](ref_counted);
  101. //Now test that reference count is ten
  102. if(ref_counted->use_count() != 10)
  103. return 1;
  104. //Now destroy the array of intrusive pointer owners
  105. //This should destroy every intrusive_ptr and because of
  106. //that reference_counted_class will be destroyed
  107. shmem.destroy_ptr(intrusive_owner_array);
  108. //Now the reference counted object should have been destroyed
  109. if(shmem.find<intrusive_ptr_owner>("ref_counted").first)
  110. return 1;
  111. //Success!
  112. return 0;
  113. }
  114. //]
  115. #include <boost/interprocess/detail/config_end.hpp>