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
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
23using namespace boost::interprocess;
24
25//This is type of the object we want to share
26struct 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
31typedef managed_shared_ptr<type_to_share, managed_mapped_file>::type shared_ptr_type;
32typedef managed_weak_ptr<type_to_share, managed_mapped_file>::type weak_ptr_type;
33
34//This is a type holding a shared pointer
35struct shared_ptr_owner
36{
37 shared_ptr_owner(const shared_ptr_type &other_shared_ptr)
38 : shared_ptr_(other_shared_ptr)
39 {}
40
41 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
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(filename: MappedFile_); }
69 ~file_remove(){ file_mapping::remove(filename: 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 (constructed_object: file.construct<type_to_share>(name: "object to share")(), managed_memory&: 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>(name: "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>(name: "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>(name: "owner1").first;
107 shared_ptr_owner *owner2 = file.find<shared_ptr_owner>(name: "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(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(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
145

source code of boost/libs/interprocess/example/doc_shared_ptr.cpp