doc_shared_ptr.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2006-2012.
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // See http://www.boost.org/libs/interprocess for documentation.
  9. //
  10. //////////////////////////////////////////////////////////////////////////////
  11. #include <boost/interprocess/detail/config_begin.hpp>
  12. #include <boost/interprocess/detail/workaround.hpp>
  13. //[doc_shared_ptr
  14. #include <boost/interprocess/managed_mapped_file.hpp>
  15. #include <boost/interprocess/smart_ptr/shared_ptr.hpp>
  16. #include <boost/interprocess/smart_ptr/weak_ptr.hpp>
  17. #include <cassert>
  18. //<-
  19. #include "../test/get_process_id_name.hpp"
  20. //->
  21. using namespace boost::interprocess;
  22. //This is type of the object we want to share
  23. struct type_to_share
  24. {};
  25. //This is the type of a shared pointer to the previous type
  26. //that will be built in the mapped file
  27. typedef managed_shared_ptr<type_to_share, managed_mapped_file>::type shared_ptr_type;
  28. typedef managed_weak_ptr<type_to_share, managed_mapped_file>::type weak_ptr_type;
  29. //This is a type holding a shared pointer
  30. struct shared_ptr_owner
  31. {
  32. shared_ptr_owner(const shared_ptr_type &other_shared_ptr)
  33. : shared_ptr_(other_shared_ptr)
  34. {}
  35. shared_ptr_owner(const shared_ptr_owner &other_owner)
  36. : shared_ptr_(other_owner.shared_ptr_)
  37. {}
  38. shared_ptr_type shared_ptr_;
  39. //...
  40. };
  41. int main ()
  42. {
  43. //Define file names
  44. //<-
  45. #if 1
  46. std::string mapped_file(boost::interprocess::ipcdetail::get_temporary_path());
  47. mapped_file += "/"; mapped_file += test::get_process_id_name();
  48. const char *MappedFile = mapped_file.c_str();
  49. #else
  50. //->
  51. const char *MappedFile = "MyMappedFile";
  52. //<-
  53. #endif
  54. //->
  55. //Destroy any previous file with the name to be used.
  56. struct file_remove
  57. {
  58. file_remove(const char *MappedFile)
  59. : MappedFile_(MappedFile) { file_mapping::remove(MappedFile_); }
  60. ~file_remove(){ file_mapping::remove(MappedFile_); }
  61. const char *MappedFile_;
  62. } remover(MappedFile);
  63. {
  64. managed_mapped_file file(create_only, MappedFile, 65536);
  65. //Construct the shared type in the file and
  66. //pass ownership to this local shared pointer
  67. shared_ptr_type local_shared_ptr = make_managed_shared_ptr
  68. (file.construct<type_to_share>("object to share")(), file);
  69. assert(local_shared_ptr.use_count() == 1);
  70. //Share ownership of the object between local_shared_ptr and a new "owner1"
  71. shared_ptr_owner *owner1 =
  72. file.construct<shared_ptr_owner>("owner1")(local_shared_ptr);
  73. assert(local_shared_ptr.use_count() == 2);
  74. //local_shared_ptr releases object ownership
  75. local_shared_ptr.reset();
  76. assert(local_shared_ptr.use_count() == 0);
  77. assert(owner1->shared_ptr_.use_count() == 1);
  78. //Share ownership of the object between "owner1" and a new "owner2"
  79. shared_ptr_owner *owner2 =
  80. file.construct<shared_ptr_owner>("owner2")(*owner1);
  81. assert(owner1->shared_ptr_.use_count() == 2);
  82. assert(owner2->shared_ptr_.use_count() == 2);
  83. assert(owner1->shared_ptr_.get() == owner2->shared_ptr_.get());
  84. //<-
  85. (void)owner2;
  86. //->
  87. //The mapped file is unmapped here. Objects have been flushed to disk
  88. }
  89. {
  90. //Reopen the mapped file and find again all owners
  91. managed_mapped_file file(open_only, MappedFile);
  92. shared_ptr_owner *owner1 = file.find<shared_ptr_owner>("owner1").first;
  93. shared_ptr_owner *owner2 = file.find<shared_ptr_owner>("owner2").first;
  94. assert(owner1 && owner2);
  95. //Check everything is as expected
  96. assert(file.find<type_to_share>("object to share").first != 0);
  97. assert(owner1->shared_ptr_.use_count() == 2);
  98. assert(owner2->shared_ptr_.use_count() == 2);
  99. assert(owner1->shared_ptr_.get() == owner2->shared_ptr_.get());
  100. //Now destroy one of the owners, the reference count drops.
  101. file.destroy_ptr(owner1);
  102. assert(owner2->shared_ptr_.use_count() == 1);
  103. //Create a weak pointer
  104. weak_ptr_type local_observer1(owner2->shared_ptr_);
  105. assert(local_observer1.use_count() == owner2->shared_ptr_.use_count());
  106. { //Create a local shared pointer from the weak pointer
  107. shared_ptr_type local_shared_ptr = local_observer1.lock();
  108. assert(local_observer1.use_count() == owner2->shared_ptr_.use_count());
  109. assert(local_observer1.use_count() == 2);
  110. }
  111. //Now destroy the remaining owner. "object to share" will be destroyed
  112. file.destroy_ptr(owner2);
  113. assert(file.find<type_to_share>("object to share").first == 0);
  114. //Test observer
  115. assert(local_observer1.expired());
  116. assert(local_observer1.use_count() == 0);
  117. //The reference count will be deallocated when all weak pointers
  118. //disappear. After that, the file is unmapped.
  119. }
  120. return 0;
  121. }
  122. //]
  123. #include <boost/interprocess/detail/config_end.hpp>