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 14 //[doc_shared_ptr 15 #include <boost/interprocess/managed_mapped_file.hpp> 16 #include <boost/interprocess/smart_ptr/shared_ptr.hpp> 17 #include <boost/interprocess/smart_ptr/weak_ptr.hpp> 18 #include <cassert> 19 //<- 20 #include "../test/get_process_id_name.hpp" 21 //-> 22 23 using namespace boost::interprocess; 24 25 //This is type of the object we want to share 26 struct type_to_share 27 {}; 28 29 //This is the type of a shared pointer to the previous type 30 //that will be built in the mapped file 31 typedef managed_shared_ptr<type_to_share, managed_mapped_file>::type shared_ptr_type; 32 typedef managed_weak_ptr<type_to_share, managed_mapped_file>::type weak_ptr_type; 33 34 //This is a type holding a shared pointer 35 struct shared_ptr_owner 36 { shared_ptr_ownershared_ptr_owner37 shared_ptr_owner(const shared_ptr_type &other_shared_ptr) 38 : shared_ptr_(other_shared_ptr) 39 {} 40 shared_ptr_ownershared_ptr_owner41 shared_ptr_owner(const shared_ptr_owner &other_owner) 42 : shared_ptr_(other_owner.shared_ptr_) 43 {} 44 45 shared_ptr_type shared_ptr_; 46 //... 47 }; 48 main()49int main () 50 { 51 //Define file names 52 //<- 53 #if 1 54 std::string mapped_file(boost::interprocess::ipcdetail::get_temporary_path()); 55 mapped_file += "/"; mapped_file += test::get_process_id_name(); 56 const char *MappedFile = mapped_file.c_str(); 57 #else 58 //-> 59 const char *MappedFile = "MyMappedFile"; 60 //<- 61 #endif 62 //-> 63 64 //Destroy any previous file with the name to be used. 65 struct file_remove 66 { 67 file_remove(const char *MappedFile) 68 : MappedFile_(MappedFile) { file_mapping::remove(MappedFile_); } 69 ~file_remove(){ file_mapping::remove(MappedFile_); } 70 const char *MappedFile_; 71 } remover(MappedFile); 72 { 73 managed_mapped_file file(create_only, MappedFile, 65536); 74 75 //Construct the shared type in the file and 76 //pass ownership to this local shared pointer 77 shared_ptr_type local_shared_ptr = make_managed_shared_ptr 78 (file.construct<type_to_share>("object to share")(), file); 79 assert(local_shared_ptr.use_count() == 1); 80 81 //Share ownership of the object between local_shared_ptr and a new "owner1" 82 shared_ptr_owner *owner1 = 83 file.construct<shared_ptr_owner>("owner1")(local_shared_ptr); 84 assert(local_shared_ptr.use_count() == 2); 85 86 //local_shared_ptr releases object ownership 87 local_shared_ptr.reset(); 88 assert(local_shared_ptr.use_count() == 0); 89 assert(owner1->shared_ptr_.use_count() == 1); 90 91 //Share ownership of the object between "owner1" and a new "owner2" 92 shared_ptr_owner *owner2 = 93 file.construct<shared_ptr_owner>("owner2")(*owner1); 94 assert(owner1->shared_ptr_.use_count() == 2); 95 assert(owner2->shared_ptr_.use_count() == 2); 96 assert(owner1->shared_ptr_.get() == owner2->shared_ptr_.get()); 97 //<- 98 (void)owner2; 99 //-> 100 //The mapped file is unmapped here. Objects have been flushed to disk 101 } 102 { 103 //Reopen the mapped file and find again all owners 104 managed_mapped_file file(open_only, MappedFile); 105 106 shared_ptr_owner *owner1 = file.find<shared_ptr_owner>("owner1").first; 107 shared_ptr_owner *owner2 = file.find<shared_ptr_owner>("owner2").first; 108 assert(owner1 && owner2); 109 110 //Check everything is as expected 111 assert(file.find<type_to_share>("object to share").first != 0); 112 assert(owner1->shared_ptr_.use_count() == 2); 113 assert(owner2->shared_ptr_.use_count() == 2); 114 assert(owner1->shared_ptr_.get() == owner2->shared_ptr_.get()); 115 116 //Now destroy one of the owners, the reference count drops. 117 file.destroy_ptr(owner1); 118 assert(owner2->shared_ptr_.use_count() == 1); 119 120 //Create a weak pointer 121 weak_ptr_type local_observer1(owner2->shared_ptr_); 122 assert(local_observer1.use_count() == owner2->shared_ptr_.use_count()); 123 124 { //Create a local shared pointer from the weak pointer 125 shared_ptr_type local_shared_ptr = local_observer1.lock(); 126 assert(local_observer1.use_count() == owner2->shared_ptr_.use_count()); 127 assert(local_observer1.use_count() == 2); 128 } 129 130 //Now destroy the remaining owner. "object to share" will be destroyed 131 file.destroy_ptr(owner2); 132 assert(file.find<type_to_share>("object to share").first == 0); 133 134 //Test observer 135 assert(local_observer1.expired()); 136 assert(local_observer1.use_count() == 0); 137 138 //The reference count will be deallocated when all weak pointers 139 //disappear. After that, the file is unmapped. 140 } 141 return 0; 142 } 143 //] 144 #include <boost/interprocess/detail/config_end.hpp> 145