1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #include <boost/interprocess/allocators/allocator.hpp>
12 #include <boost/interprocess/containers/vector.hpp>
13 #include <boost/interprocess/managed_shared_memory.hpp>
16 #include "get_process_id_name.hpp"
18 using namespace boost::interprocess
;
20 template <class CharT
>
21 struct filename_traits
;
24 struct filename_traits
<char>
27 static const char* get()
28 { return test::get_process_id_name(); }
30 static std::string filename
;
33 #ifdef BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES
36 struct filename_traits
<wchar_t>
39 static const wchar_t* get()
40 { return test::get_process_id_wname(); }
42 static std::wstring filename
;
45 #endif //#ifdef BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES
49 int test_managed_shared_memory()
51 const int ShmemSize
= 65536;
52 const CharT
*const ShmemName
= filename_traits
<CharT
>::get();
54 //STL compatible allocator object for memory-mapped shmem
55 typedef allocator
<int, managed_shared_memory::segment_manager
>
57 //A vector that uses that allocator
58 typedef boost::interprocess::vector
<int, allocator_int_t
> MyVect
;
61 //Remove the shmem it is already created
62 shared_memory_object::remove(ShmemName
);
65 void *array
[std::size_t(max
)];
66 //Named allocate capable shared memory allocator
67 managed_shared_memory
shmem(create_only
, ShmemName
, ShmemSize
);
70 //Let's allocate some memory
71 for(i
= 0; i
< max
; ++i
){
72 array
[std::ptrdiff_t(i
)] = shmem
.allocate(i
+1u);
75 //Deallocate allocated memory
76 for(i
= 0; i
< max
; ++i
){
77 shmem
.deallocate(array
[std::ptrdiff_t(i
)]);
82 //Remove the shmem it is already created
83 shared_memory_object::remove(ShmemName
);
85 //Named allocate capable memory mapped shmem managed memory class
86 managed_shared_memory
tmp(create_only
, ShmemName
, ShmemSize
);
89 //Remove the shmem it is already created
90 shared_memory_object::remove(ShmemName
);
92 //Now re-create it with create or open
93 managed_shared_memory
shmem(open_or_create
, ShmemName
, ShmemSize
);
95 //Construct the STL-like allocator with the segment manager
96 const allocator_int_t
myallocator (shmem
.get_segment_manager());
99 MyVect
*shmem_vect
= shmem
.construct
<MyVect
> ("MyVector") (myallocator
);
101 //Test that vector can be found via name
102 if(shmem_vect
!= shmem
.find
<MyVect
>("MyVector").first
)
105 //Destroy and check it is not present
106 shmem
.destroy
<MyVect
> ("MyVector");
107 if(0 != shmem
.find
<MyVect
>("MyVector").first
)
110 //Construct a vector in the memory-mapped shmem
111 shmem_vect
= shmem
.construct
<MyVect
> ("MyVector") (myallocator
);
114 //Map preexisting shmem again in memory
115 managed_shared_memory
shmem(open_only
, ShmemName
);
117 //Check vector is still there
118 MyVect
*shmem_vect
= shmem
.find
<MyVect
>("MyVector").first
;
124 //Map preexisting shmem again in copy-on-write
125 managed_shared_memory
shmem(open_copy_on_write
, ShmemName
);
127 //Check vector is still there
128 MyVect
*shmem_vect
= shmem
.find
<MyVect
>("MyVector").first
;
133 shmem
.destroy_ptr(shmem_vect
);
135 //Make sure vector is erased
136 shmem_vect
= shmem
.find
<MyVect
>("MyVector").first
;
140 //Now check vector is still in the shmem
142 //Map preexisting shmem again in copy-on-write
143 managed_shared_memory
shmem(open_copy_on_write
, ShmemName
);
145 //Check vector is still there
146 MyVect
*shmem_vect
= shmem
.find
<MyVect
>("MyVector").first
;
151 //Map preexisting shmem again in memory
152 managed_shared_memory
shmem(open_or_create
, ShmemName
, ShmemSize
);
154 //Check vector is still there
155 MyVect
*shmem_vect
= shmem
.find
<MyVect
>("MyVector").first
;
161 //Map preexisting shmem again in read-only
162 managed_shared_memory
shmem(open_read_only
, ShmemName
);
164 //Check vector is still there
165 MyVect
*shmem_vect
= shmem
.find
<MyVect
>("MyVector").first
;
169 #ifndef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
171 managed_shared_memory::size_type old_free_memory
;
173 //Map preexisting shmem again in memory
174 managed_shared_memory
shmem(open_only
, ShmemName
);
175 old_free_memory
= shmem
.get_free_memory();
179 managed_shared_memory::grow(ShmemName
, ShmemSize
);
181 //Map preexisting shmem again in memory
182 managed_shared_memory
shmem(open_only
, ShmemName
);
184 //Check vector is still there
185 MyVect
*shmem_vect
= shmem
.find
<MyVect
>("MyVector").first
;
189 if(shmem
.get_size() != (ShmemSize
*2))
191 if(shmem
.get_free_memory() <= old_free_memory
)
195 managed_shared_memory::size_type old_free_memory
, next_free_memory
,
196 old_shmem_size
, next_shmem_size
, final_shmem_size
;
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();
204 //Now shrink the shmem
205 managed_shared_memory::shrink_to_fit(ShmemName
);
208 //Map preexisting shmem again in memory
209 managed_shared_memory
shmem(open_only
, ShmemName
);
210 next_shmem_size
= shmem
.get_size();
212 //Check vector is still there
213 MyVect
*shmem_vect
= shmem
.find
<MyVect
>("MyVector").first
;
217 next_free_memory
= shmem
.get_free_memory();
218 if(next_free_memory
>= old_free_memory
)
220 if(old_shmem_size
<= next_shmem_size
)
224 //Now destroy the vector
226 //Map preexisting shmem again in memory
227 managed_shared_memory
shmem(open_only
, ShmemName
);
229 //Destroy and check it is not present
230 shmem
.destroy
<MyVect
>("MyVector");
231 if(0 != shmem
.find
<MyVect
>("MyVector").first
)
235 //Now shrink the shmem
236 managed_shared_memory::shrink_to_fit(ShmemName
);
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
)
245 #endif //ifndef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
248 //Now test move semantics
249 managed_shared_memory
original(open_only
, ShmemName
);
250 managed_shared_memory
move_ctor(boost::move(original
));
251 managed_shared_memory move_assign
;
252 move_assign
= boost::move(move_ctor
);
253 move_assign
.swap(original
);
256 shared_memory_object::remove(ShmemName
);
263 r
= test_managed_shared_memory
<char>();
265 #ifdef BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES
266 r
= test_managed_shared_memory
<wchar_t>();