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

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