1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2004-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
11 #include <boost/interprocess/detail/workaround.hpp>
12
13 #if defined(BOOST_INTERPROCESS_MAPPED_FILES)
14
15 #include <boost/interprocess/allocators/allocator.hpp>
16 #include <boost/interprocess/containers/vector.hpp>
17 #include <boost/interprocess/managed_mapped_file.hpp>
18 #include <cstdio>
19 #include <string>
20 #include "get_process_id_name.hpp"
21
22 using namespace boost::interprocess;
23
get_filename()24 inline std::string get_filename()
25 {
26 std::string ret (ipcdetail::get_temporary_path());
27 ret += "/";
28 ret += test::get_process_id_name();
29 return ret;
30 }
31
main()32 int main ()
33 {
34 const int FileSize = 65536*10;
35 std::string filename(get_filename());
36 const char *FileName = filename.c_str();
37
38 //STL compatible allocator object for memory-mapped file
39 typedef allocator<int, managed_mapped_file::segment_manager>
40 allocator_int_t;
41 //A vector that uses that allocator
42 typedef boost::interprocess::vector<int, allocator_int_t> MyVect;
43
44 {
45 //Remove the file it is already created
46 file_mapping::remove(FileName);
47
48 const int max = 100;
49 void *array[max];
50 //Named allocate capable shared memory allocator
51 managed_mapped_file mfile(create_only, FileName, FileSize);
52
53 int i;
54 //Let's allocate some memory
55 for(i = 0; i < max; ++i){
56 array[i] = mfile.allocate(i+1);
57 }
58
59 //Deallocate allocated memory
60 for(i = 0; i < max; ++i){
61 mfile.deallocate(array[i]);
62 }
63 }
64
65 {
66 //Remove the file it is already created
67 file_mapping::remove(FileName);
68
69 //Named allocate capable memory mapped file managed memory class
70 managed_mapped_file mfile(create_only, FileName, FileSize);
71
72 //Construct the STL-like allocator with the segment manager
73 const allocator_int_t myallocator (mfile.get_segment_manager());
74
75 //Construct vector
76 MyVect *mfile_vect = mfile.construct<MyVect> ("MyVector") (myallocator);
77
78 //Test that vector can be found via name
79 if(mfile_vect != mfile.find<MyVect>("MyVector").first)
80 return -1;
81
82 //Destroy and check it is not present
83 mfile.destroy<MyVect> ("MyVector");
84 if(0 != mfile.find<MyVect>("MyVector").first)
85 return -1;
86
87 //Construct a vector in the memory-mapped file
88 mfile_vect = mfile.construct<MyVect> ("MyVector") (myallocator);
89
90 //Flush cached data from memory-mapped file to disk
91 mfile.flush();
92 }
93 {
94 //Map preexisting file again in memory
95 managed_mapped_file mfile(open_only, FileName);
96
97 //Check vector is still there
98 MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
99 if(!mfile_vect)
100 return -1;
101 }
102
103 {
104 {
105 //Map preexisting file again in copy-on-write
106 managed_mapped_file mfile(open_copy_on_write, FileName);
107
108 //Check vector is still there
109 MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
110 if(!mfile_vect)
111 return -1;
112
113 //Erase vector
114 mfile.destroy_ptr(mfile_vect);
115
116 //Make sure vector is erased
117 mfile_vect = mfile.find<MyVect>("MyVector").first;
118 if(mfile_vect)
119 return -1;
120 }
121 //Now check vector is still in the file
122 {
123 //Map preexisting file again in copy-on-write
124 managed_mapped_file mfile(open_copy_on_write, FileName);
125
126 //Check vector is still there
127 MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
128 if(!mfile_vect)
129 return -1;
130 }
131 }
132 {
133 //Map preexisting file again in copy-on-write
134 managed_mapped_file mfile(open_read_only, FileName);
135
136 //Check vector is still there
137 MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
138 if(!mfile_vect)
139 return -1;
140 }
141 {
142 managed_mapped_file::size_type old_free_memory;
143 {
144 //Map preexisting file again in memory
145 managed_mapped_file mfile(open_only, FileName);
146 old_free_memory = mfile.get_free_memory();
147 }
148
149 //Now grow the file
150 managed_mapped_file::grow(FileName, FileSize);
151
152 //Map preexisting file again in memory
153 managed_mapped_file mfile(open_only, FileName);
154
155 //Check vector is still there
156 MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
157 if(!mfile_vect)
158 return -1;
159
160 if(mfile.get_size() != (FileSize*2))
161 return -1;
162 if(mfile.get_free_memory() <= old_free_memory)
163 return -1;
164 }
165 {
166 managed_mapped_file::size_type old_free_memory, next_free_memory,
167 old_file_size, next_file_size, final_file_size;
168 {
169 //Map preexisting file again in memory
170 managed_mapped_file mfile(open_only, FileName);
171 old_free_memory = mfile.get_free_memory();
172 old_file_size = mfile.get_size();
173 }
174
175 //Now shrink the file
176 managed_mapped_file::shrink_to_fit(FileName);
177
178 {
179 //Map preexisting file again in memory
180 managed_mapped_file mfile(open_only, FileName);
181 next_file_size = mfile.get_size();
182
183 //Check vector is still there
184 MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
185 if(!mfile_vect)
186 return -1;
187
188 next_free_memory = mfile.get_free_memory();
189 if(next_free_memory >= old_free_memory)
190 return -1;
191 if(old_file_size <= next_file_size)
192 return -1;
193 }
194
195 //Now destroy the vector
196 {
197 //Map preexisting file again in memory
198 managed_mapped_file mfile(open_only, FileName);
199
200 //Destroy and check it is not present
201 mfile.destroy<MyVect>("MyVector");
202 if(0 != mfile.find<MyVect>("MyVector").first)
203 return -1;
204 }
205
206 //Now shrink the file
207 managed_mapped_file::shrink_to_fit(FileName);
208 {
209 //Map preexisting file again in memory
210 managed_mapped_file mfile(open_only, FileName);
211 final_file_size = mfile.get_size();
212 if(next_file_size <= final_file_size)
213 return -1;
214 }
215 {
216 //Now test move semantics
217 managed_mapped_file original(open_only, FileName);
218 managed_mapped_file move_ctor(boost::move(original));
219 managed_mapped_file move_assign;
220 move_assign = boost::move(move_ctor);
221 move_assign.swap(original);
222 }
223 }
224
225 file_mapping::remove(FileName);
226 return 0;
227 }
228
229 #else //#if defined(BOOST_INTERPROCESS_MAPPED_FILES)
230
main()231 int main()
232 {
233 return 0;
234 }
235
236 #endif//#if defined(BOOST_INTERPROCESS_MAPPED_FILES)
237