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
22using namespace boost::interprocess;
23
24template <class CharT>
25struct filename_traits;
26
27template <>
28struct filename_traits<char>
29{
30
31 static const char* get()
32 { return filename.c_str(); }
33
34 static std::string filename;
35};
36
37std::string filename_traits<char>::filename = get_filename();
38
39
40#ifdef BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES
41
42template <>
43struct filename_traits<wchar_t>
44{
45
46 static const wchar_t* get()
47 { return filename.c_str(); }
48
49 static std::wstring filename;
50};
51
52std::wstring filename_traits<wchar_t>::filename = get_wfilename();
53
54#endif //#ifdef BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES
55
56template<class CharT>
57int test_managed_mapped_file()
58{
59 const int FileSize = 65536*10;
60 const CharT *FileName = filename_traits<CharT>::get();
61
62 //STL compatible allocator object for memory-mapped file
63 typedef allocator<int, managed_mapped_file::segment_manager>
64 allocator_int_t;
65 //A vector that uses that allocator
66 typedef boost::interprocess::vector<int, allocator_int_t> MyVect;
67
68 {
69 //Remove the file it is already created
70 file_mapping::remove(filename: FileName);
71
72 const int max = 100;
73 void *array[std::size_t(max)];
74 //Named allocate capable shared memory allocator
75 managed_mapped_file mfile(create_only, FileName, FileSize);
76
77 std::size_t i;
78 //Let's allocate some memory
79 for(i = 0; i < max; ++i){
80 array[std::ptrdiff_t(i)] = mfile.allocate(nbytes: i+1u);
81 }
82
83 //Deallocate allocated memory
84 for(i = 0; i < max; ++i){
85 mfile.deallocate(addr: array[std::ptrdiff_t(i)]);
86 }
87 }
88
89 {
90 //Remove the file it is already created
91 file_mapping::remove(filename: FileName);
92 //Named allocate capable memory mapped file managed memory class
93 managed_mapped_file tmp(create_only, FileName, FileSize);
94 }
95 {
96 //Remove the file it is already created
97 file_mapping::remove(filename: FileName);
98
99 //Now re-create it with create or open
100 managed_mapped_file mfile(open_or_create, FileName, FileSize);
101
102 //Construct the STL-like allocator with the segment manager
103 const allocator_int_t myallocator (mfile.get_segment_manager());
104
105 //Construct vector
106 MyVect *mfile_vect = mfile.construct<MyVect> (name: "MyVector") (myallocator);
107
108 //Test that vector can be found via name
109 if(mfile_vect != mfile.find<MyVect>(name: "MyVector").first)
110 return -1;
111
112 //Destroy and check it is not present
113 mfile.destroy<MyVect> (name: "MyVector");
114 if(0 != mfile.find<MyVect>(name: "MyVector").first)
115 return -1;
116
117 //Construct a vector in the memory-mapped file
118 mfile_vect = mfile.construct<MyVect> (name: "MyVector") (myallocator);
119
120 //Flush cached data from memory-mapped file to disk
121 mfile.flush();
122 }
123 {
124 //Map preexisting file again in memory
125 managed_mapped_file mfile(open_only, FileName);
126
127 //Check vector is still there
128 MyVect *mfile_vect = mfile.find<MyVect>(name: "MyVector").first;
129 if(!mfile_vect)
130 return -1;
131 }
132 {
133 //Map preexisting file again in memory
134 managed_mapped_file mfile(open_or_create, FileName, FileSize);
135
136 //Check vector is still there
137 MyVect *mfile_vect = mfile.find<MyVect>(name: "MyVector").first;
138 if(!mfile_vect)
139 return -1;
140 }
141 {
142 {
143 //Map preexisting file again in copy-on-write
144 managed_mapped_file mfile(open_copy_on_write, FileName);
145
146 //Check vector is still there
147 MyVect *mfile_vect = mfile.find<MyVect>(name: "MyVector").first;
148 if(!mfile_vect)
149 return -1;
150
151 //Erase vector
152 mfile.destroy_ptr(ptr: mfile_vect);
153
154 //Make sure vector is erased
155 mfile_vect = mfile.find<MyVect>(name: "MyVector").first;
156 if(mfile_vect)
157 return -1;
158 }
159 //Now check vector is still in the file
160 {
161 //Map preexisting file again in copy-on-write
162 managed_mapped_file mfile(open_copy_on_write, FileName);
163
164 //Check vector is still there
165 MyVect *mfile_vect = mfile.find<MyVect>(name: "MyVector").first;
166 if(!mfile_vect)
167 return -1;
168 }
169 }
170 {
171 //Map preexisting file again in read-only
172 managed_mapped_file mfile(open_read_only, FileName);
173
174 //Check vector is still there
175 MyVect *mfile_vect = mfile.find<MyVect>(name: "MyVector").first;
176 if(!mfile_vect)
177 return -1;
178 }
179 {
180 managed_mapped_file::size_type old_free_memory;
181 {
182 //Map preexisting file again in memory
183 managed_mapped_file mfile(open_only, FileName);
184 old_free_memory = mfile.get_free_memory();
185 }
186
187 //Now grow the file
188 managed_mapped_file::grow(filename: FileName, extra_bytes: FileSize);
189
190 //Map preexisting file again in memory
191 managed_mapped_file mfile(open_only, FileName);
192
193 //Check vector is still there
194 MyVect *mfile_vect = mfile.find<MyVect>(name: "MyVector").first;
195 if(!mfile_vect)
196 return -1;
197
198 if(mfile.get_size() != (FileSize*2))
199 return -1;
200 if(mfile.get_free_memory() <= old_free_memory)
201 return -1;
202 }
203 {
204 managed_mapped_file::size_type old_free_memory, next_free_memory,
205 old_file_size, next_file_size, final_file_size;
206 {
207 //Map preexisting file again in memory
208 managed_mapped_file mfile(open_only, FileName);
209 old_free_memory = mfile.get_free_memory();
210 old_file_size = mfile.get_size();
211 }
212
213 //Now shrink the file
214 managed_mapped_file::shrink_to_fit(filename: FileName);
215
216 {
217 //Map preexisting file again in memory
218 managed_mapped_file mfile(open_only, FileName);
219 next_file_size = mfile.get_size();
220
221 //Check vector is still there
222 MyVect *mfile_vect = mfile.find<MyVect>(name: "MyVector").first;
223 if(!mfile_vect)
224 return -1;
225
226 next_free_memory = mfile.get_free_memory();
227 if(next_free_memory >= old_free_memory)
228 return -1;
229 if(old_file_size <= next_file_size)
230 return -1;
231 }
232
233 //Now destroy the vector
234 {
235 //Map preexisting file again in memory
236 managed_mapped_file mfile(open_only, FileName);
237
238 //Destroy and check it is not present
239 mfile.destroy<MyVect>(name: "MyVector");
240 if(0 != mfile.find<MyVect>(name: "MyVector").first)
241 return -1;
242 }
243
244 //Now shrink the file
245 managed_mapped_file::shrink_to_fit(filename: FileName);
246 {
247 //Map preexisting file again in memory
248 managed_mapped_file mfile(open_only, FileName);
249 final_file_size = mfile.get_size();
250 if(next_file_size <= final_file_size)
251 return -1;
252 }
253 {
254 //Now test move semantics
255 managed_mapped_file original(open_only, FileName);
256 managed_mapped_file move_ctor(boost::move(t&: original));
257 managed_mapped_file move_assign;
258 move_assign = boost::move(t&: move_ctor);
259 move_assign.swap(other&: original);
260 }
261 }
262
263 file_mapping::remove(filename: FileName);
264 return 0;
265}
266
267int main ()
268{
269 int r;
270 r = test_managed_mapped_file<char>();
271 if(r) return r;
272 #ifdef BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES
273 r = test_managed_mapped_file<wchar_t>();
274 if(r) return r;
275 #endif
276 return 0;
277}
278
279
280#else //#if defined(BOOST_INTERPROCESS_MAPPED_FILES)
281
282int main()
283{
284 return 0;
285}
286
287#endif//#if defined(BOOST_INTERPROCESS_MAPPED_FILES)
288

source code of boost/libs/interprocess/test/managed_mapped_file_test.cpp